áááşášáááŹá፠Habrá á
áŹáĄáŻááşááŻááşááąáááş ááźááşáááşááąááŤááźáąáŹááşá¸ áĄááááąá¸áĄááşááŤáááşá"
BPF virtual machine áááş áááşáááşáááŻá¸áááşááąááźáŽá¸ áááşáá˝áąáˇáá˝ááş áááşááźá˝á
á˝áŹáĄááŻáśá¸ááźáŻááąááąáŹááźáąáŹááˇáş áááşá¸ááááşáá
á˝ááşá¸áááşááťáŹá¸áážááˇáş áááşáážááĄááźáąáĄááąáĄááźáąáŹááşá¸ááąáŹáşááźáááˇáş ááąáŹááşá¸ááŤá¸ááᯠáááˇáşáĄáá˝ááş ááŹááŹááźááşááŹá¸ááŤáááşá
áááźáŹááąá¸ááŽáážá
áşááťáŹá¸áĄáá˝ááşá¸á á
á˝ááşá¸ááąáŹááşáááşááźááˇáşááŹá¸ááąáŹ packet ááŻááşááąáŹááşááźááşá¸ áááŻáĄááşáááˇáşááá
ášá
ááťáŹá¸áá˝ááş Linux kernel ááááˇáşáááşááťááşááťáŹá¸ááᯠááťáąáŹáşááźáąá¸ááąá¸áááş ááááŻááááşááąá¸ááááááŹááťáŹá¸áážááˇáş áááşá¸á
áá
áşááťáŹá¸áááş áá°ááźááŻááşááťáŹá¸ááŹáá˛áˇáááşá á¤áĄááťááŻá¸áĄá
áŹá¸áááąáááşá¸áĄá
áŹá¸ááŻáśá¸áááşá¸áááŹááťáŹá¸áá˛áážáá
áşááŻááŻááąáŤáşáááşá kernel áááŻáážáąáŹááşáá˝ááşá¸ (kernel bypass) áážááˇáş kernel network layer ááᯠááťáąáŹáşááźááşáᏠuser space ááž packet processing áĄáŹá¸ááŻáśá¸ááᯠááŻááşááąáŹááşáááş áá˝ááˇáşááźáŻáááşá kernel áááŻááťáąáŹáşááźááşááźááşá¸áááşáááşá¸ network card áááŻááááşá¸ááťáŻááşááźááşá¸áááşá¸ááŤáááşáááşá áĄááŻáśá¸ááźáŻáá°ááąááŹ. áá
áşáááşá¸áááŻáááąáŹáş áá˝ááşáááşáááşáá
áşááŻááźááˇáş áĄááŻááşááŻááşááąáŹáĄá፠ááťá˝ááşáŻááşáááŻáˇáááş ááŹááşááąáŹááşá¸ááᯠáĄáŹá¸áááŻá¸áááşá áĄááŻáśá¸ááźáŻáá°ááąááŹ.
áá˝ááşáááşáááşá ááááşá¸ááťáŻááşáážáŻ áĄááźááˇáşáĄáááᯠáĄááŻáśá¸ááźáŻáá°-áĄáŹááŹáááááŻááááşáááŻáˇ áá˝ážá˛ááźáąáŹááşá¸ááźááşá¸ááźááˇáşá ááťá˝ááşáŻááşáááŻáˇáááş 10Gb/s áááŻáˇáááŻááş áááŻáˇáááşááźááˇáşááŹá¸ááąáŹ áĄááźááşáážáŻááşá¸ááźááˇáş ááŻááşááąáŹááşááąáŹáĄááŤáá˝ááş áĄáá˝ááşáĄááąá¸ááźáŽá¸áááˇáş kernel overhead (context switching, network layer processing, interrupts, etc.) ááᯠááťážáąáŹáˇááťááąá¸ááŤáááşá Kernel bypass áážááˇáş áĄááźáŹá¸áĄááşášááŤáááşááťáŹá¸ ááąáŤááşá¸á
ááşáážáŻ (batch processing) áážááˇáş áááŻáá
ááŻááş á
á˝ááşá¸ááąáŹááşáááş ááťáááşáážáááźááşá¸ (NUMA á
áŹáááşá¸áááŻááş, CPU áĄááŽá¸ááťááşá
áááşáááŻáˇ) áááş ááŻáśá¸á
á˝á˛áá°ááąááŹáážá á
á˝ááşá¸ááąáŹááşáááşááźááˇáş áá˝ááşáááşááŻááşááąáŹááşááźááşá¸á áĄááźáąááśááťáŹá¸áážááˇáş áááŻááşááŽááŤáááşá packet processing áá˝ááş á¤ááťááşá¸áááşáážáŻáĄáá
áşá á
áśááá°ááŹááźááźá
áşáááŻááşáááşá
áĄááŻáśá¸ááźáŻáá°ááąááŹáážá áá˝ááşáááş áĄááźááşáĄáážááşáááşáá˝ááşáážáŻááťáŹá¸ááᯠá áŻá ááşá¸ááŹáá˝ááş áĄáŹá¸áááşá¸ááťááşááťáŹá¸á á˝áŹáážááááşá
- OS kernel áááş ááŹáˇááşáá˛áĄáááşá¸áĄááźá áşááťáŹá¸áĄáá˝ááş abstraction layer áá áşááŻááźá áşáááşá áĄááŻáśá¸ááźáŻáá°áĄáŹááŹáááááŻááááşááťáŹá¸áááş áááşá¸áááŻáˇááĄáááşá¸áĄááźá áşááťáŹá¸ááᯠáááŻááşáááŻááşá áŽááśáááˇáşáá˝á˛ááááşááźá áşááąáŹááźáąáŹááˇáşá áááşá¸áááŻáˇááááŻááşáááŻááş hardware áááŻáááşá¸ á áŽááśáááˇáşáá˝á˛ááááşááźá áşáááşá áááşá¸áááş áááˇáşáááŻááşáááŻááşááŹááşááąáŹááşá¸ááťáŹá¸ááᯠááááŻááááşááŹá¸áážáááźááşá¸ááᯠáááźáŹáááááŻáááŻáááşá
- ááťá˝ááşáŻááşáááŻáˇáááş kernel space ááᯠááŻáśá¸ááŻáśá¸ááťáŹá¸ááťáŹá¸ á á˝ááˇáşáá˝ážááşááąááąáŹááźáąáŹááˇáşá kernel ááž ááśáˇáááŻá¸ááąá¸ááąáŹ áá˝ááşáááşááťáááşáááşáážáŻ ááŻááşááąáŹááşáááŻááşá á˝ááşá¸áĄáŹá¸ááŻáśá¸áááŻáááşá¸ á á˝ááˇáşáá˝ážááşáááŻááşááŤáááşá áĄááŻáśá¸ááźáŻáá°ááąááŹáá˝ááşááááŻááááşááťáŹá¸áááş kernel áááŻáˇáááŻááş operating system áážááąá¸ááąáŹááşááŹá¸ááźáŽá¸ááźá áşáááˇáşáĄááşášááŤáááşááťáŹá¸ááᯠááźááşáááşááźááşáááşáááŤáááşá
- ááááŻááááşááťáŹá¸áááş áááşá¸áááŻáˇá áĄááźááşáĄáážááşáááşáá˝ááşáážáŻááᯠááźááşá¸áááşá á˝áŹ áááˇáşáááşááŹá¸ááźáŽá¸ áááşáááşáážáŻá áá áşá áĄááźáŹá¸áĄá áááşáĄáááŻááşá¸ááťáŹá¸áážááˇáş ááąáŤááşá¸á ááşá¸ááźááşá¸ááž ááŹá¸ááŽá¸ááąá¸áááˇáş sandbox ááŻááşáá˝ááş ááŻááşááąáŹááşáááşá
áĄáážá áşááŹááĄáŹá¸ááźááˇáşá user space áá˝ááş networking ááŻááşááąáŹáĄááŤá packet processing ááᯠkernel ááž user space áááŻáˇ áá˝ážáąáˇááźááşá¸ááźááˇáş á á˝ááşá¸ááąáŹááşáááş áĄááťááŻá¸ááťáąá¸áá°á¸ááťáŹá¸ ááážáááŤáááşá XDP áááş áááˇáşááťááşáááşáĄááźá áş áĄáááĄááťááŻááşááąáŹááşáááş- áááşá¸áááş áĄááŻáśá¸ááźáŻáá°ááąáᏠ(filtersá ááźáąáážááşá¸áá°ááťáŹá¸á áááşá¸ááźáąáŹááşá¸ááąá¸ááźááşá¸á áááş) ááž áá˝ááşáááşááťáááşáááşáážáŻááááŻááááşááťáŹá¸ááᯠkernel space áááŻáˇ áá˝ážáąáˇáááşá XDP áááş áááşáááşáá áşááŻáááş áá˝ááşáááşáĄááşááŹááąáˇá áşáááŻáááážááşáááşáážááˇáş áááşá¸áááş kernel áá˝ááşáááşáá˝á˛á áá áşáááŻáˇáá áááşááŽáá˝ááş áá˝ááşáááşááŻááşááąáŹááşááťááşááᯠááŻááşááąáŹááşáááŻááşá áąááŤáááşá ááááşáĄááąááźááˇáş packet processing speed ááááááŹááŹáááŻá¸ááŹáááşá áááŻáˇááąáŹáşá kernel áááş ááŻáśá¸á á˝á˛áá°áĄáŹá¸ áááşá¸áááŻáˇá ááááŻááááşááťáŹá¸ááᯠkernel space áá˝ááş áááşáááŻáˇááŻááşááąáŹááşáá˝ááˇáşááźáŻááááşá¸á ááŽááąá¸áá˝ááşá¸ááᯠáááźáąáááş BPF áááŻáᏠááŹáá˛áááŻáᏠááąáˇááŹááźááˇáşááĄáąáŹááşá
BPF áážááˇáş eBPF
ááŹáááşáážáŻááşáá˝áąá¸ááąááąáŹáşáááşá¸ BPF (Berkeley Packet Filtering) áááş áĄáážááşááááşááąáŹáˇ virtual machine model áá áşááŻááźá áşáááşá ᤠvirtual machine áááş packet filtering ááᯠáááŻááşáá˝ááşáááş áá°áá ááŽáááŻááşá¸áá˝á˛ááŹá¸ááąáŹááźáąáŹááˇáş ááŹáááşááźá áşáááşá
BPF áááŻáĄááŻáśá¸ááźáŻáááˇáşáĄááťáąáŹáşááźáŹá¸ááŻáśá¸ááááááŹááťáŹá¸áá˛áážáá
áşááŻááźá
áşáááşá tcpdump
. packets ááťáŹá¸ááᯠáááşá¸áá°ááŹáá˝ááş áĄááŻáśá¸ááźáŻáááşá tcpdump
áĄááŻáśá¸ááźáŻáá°áááş packets áááŻá
á
áşááŻááşáááş expression áá
áşááŻááᯠáááşáážááşáááŻááşáááşá á¤áĄááŻáśá¸áĄáážáŻááşá¸áážááˇáşáááŻááşááŽááąáŹ áááşááąáˇááşáťááťáŹá¸áááŻáᏠáááşá¸áá°áááşááźá
áşáááşá áĽáááŹáĄáŹá¸ááźááˇáş âáĄááŻáśá¸áĄáážáŻááşá¸átcp dst port 80
â áááş port 80 áá˝ááşááąáŹááşáážáááŹááąáŹ TCP packet áĄáŹá¸ááŻáśá¸áááŻáááşáá˝ážááşá¸áááşá compiler áááş áááşá¸ááᯠ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-bit á ááŹá¸ááŻáśá¸áĄááźá áş offset 16 áá˝ááş packet ááᯠaccumulator áá˛áááŻáˇ áááˇáşááŤá Offset 12 áááş packet á ethertype áážááˇáş áááŻááşááŽáááşá
- áá˝ážááşááźáŹá¸ááťááş (001)- á áŻááąáŹááşá¸ááááááŹáážááááşáááŻá¸ááᯠ0x86dd áážááˇáş IPv6 áĄáá˝ááş ethertype áááşáááŻá¸áážááˇáş áážááŻááşá¸áážááşáááşá ááááşáážááşááŤá ááááŻááááşááąáŹááşááŹáááş áá˝ážááşááźáŹá¸ááťááş (002) áááŻáˇáá˝áŹá¸á áááŻááşááŤá (006) áááŻáˇáá˝áŹá¸ááŤá
- áá˝ážááşááźáŹá¸ááťááş (006): áááşáááŻá¸ááᯠ0x800 (IPv4 áĄáá˝ááş áĄáŽááŹáĄááťááŻá¸áĄá áŹá¸áááşáááŻá¸) áážááˇáş áážááŻááşá¸áážááşáááşá áĄááźáąáážááşááŤá ááááŻááááşáááş (007) áááŻáˇ áááŻááşááŤá (015) áááŻáˇáá˝áŹá¸ááŤáááşá
packet filtering program ááááşáá áşááŻááźááşáááŹáááťááşá¸ á áááşáááŻáˇááźá áşáááşá áááşá¸áááş áĄááťáŹá¸áĄáŹá¸ááźááˇáş Boolean ááźá áşáááşá ááŻááááŻááşááąáŹáááşáááŻá¸ (áá˝ážááşááźáŹá¸ááťááş (014)) ááᯠááźááşáááŻááźááşá¸áááş áááşáááşááᯠáááşááśáá˛áˇááźáąáŹááşá¸áážááˇáş ááŻááááşáááŻá¸ (áá˝ážááşááźáŹá¸ááťááş (015)) ááźááşááŹááźááşá¸ááᯠáááŻáááŻáááşáážáŹ áááşááąáˇááşáťááᯠáááşáááśááźáąáŹááşá¸ áááŻáááŻáááşá
BPF virtual machine áážááˇáş áááşá¸á bytecode ááᯠSteve McCann áážááˇáş Van Jacobson áááŻáˇá áááá ááŻáážá
áşáážáąáŹááşá¸áááŻááşá¸áá˝ááş áááşá¸áááŻáˇá á
áŹáááşá¸ááᯠááŻááşááąááąáŹáĄá፠áĄáááŻááźáŻáá˛áˇáááşá
BPF áááş virtual machine áá
áşááŻááźá
áşááąáŹááźáąáŹááˇáşá áááşá¸áááş ááááŻááááşááťáŹá¸áááşáááşáááˇáş áááşáááşá¸ááťááşááᯠáááşáážááşááąá¸áááşá bytecode áĄááźááşá áááşá¸áááş batch memory model (load áá˝ážááşááźáŹá¸ááťááşááťáŹá¸ááᯠbatch áĄáá˝ááş áá˝ááşáááŻááşááąáŹáááşá¸ááźááˇáş áĄááŻáśá¸ááźáŻáááş)á áážááşááŻáśáááşááťáŹá¸ (A áážááˇáş X; accumulator áážááˇáş index registers)á scratch memory storage áážááˇáş implicit program counter áááŻáˇáááŻáááşá¸ áááşáážááşááąá¸ááŤáááşá á
áááşáááşá
áŹá¸á
ááŹááąáŹááşá¸ááŹá BPF bytecode ááᯠMotorola 6502 ISA áá˛áˇááąáŹááşáážáŹ ááŻáśá
áśááŻááşááŹá¸ááŤáááşá Steve McCann á áá°áˇáĄáá˛áážáŹ áážááşááááááŻááŤáá˛á
BPF ááśáˇáááŻá¸áážáŻááᯠJay Schullist áááźááŻá¸á
áŹá¸áĄáŹá¸ááŻááşáážáŻááźááˇáş ááŹá¸áážááşá¸ v2.5 áážááˇáşáĄáááşáá˝ááş Linux kernel áá˝ááşáĄááąáŹááşáĄáááşááąáŹáşááŹá¸áááşá Eric Dumaset áááş JIT ááŻááşáá˝ááşáĄááŻááşááŻááşáááş BPF á
ááŹá¸ááźááşáĄáŹá¸ ááźááşáááşááŽáááŻááşá¸ááŻááşááąáŹáĄá፠BPF ááŻááşáááş 2011 ááŻáážá
áşáĄáá áááźáąáŹááşá¸áá˛ááąá¸á፠(áĄáááşá¸áĄááźá
áş-
ááąáŹááşáááŻááşá¸áá˝ááşá 2014 ááŻáážá áşáá˝ááş Alexey Starovoitov áááş BPF áĄáá˝ááş JIT ááášáááŹá¸áĄáá áşáááŻáĄáááŻááźáŻáá˛áˇáááşá ááááşááąáŹáˇá áᎠJIT áĄáá áşáᏠBPF áĄááźáąááś ááááŻááŹáĄáá áşááźá áşááŹááźáŽá¸ eBPF áááŻáˇ ááąáŤáşááŤáááşá VM áážá áşááŻááŻáśá¸áááş áĄááťáááşáĄáááşááźáŹ áĄáá°áážáááąáá˛áˇáááşáᯠááťá˝ááşááąáŹáşáááşáááşá áááŻáˇááąáŹáş áááşáážááá˝ááş packet filtering ááᯠeBPF ááąáŤáşáĄááźáąááśá áĄááąáŹááşáĄáááşááąáŹáşááŤáááşá áĄáážááşáážáŹá ááąááşááŽá áŹáá˝ááşá áŹáááşá¸ááťáŹá¸áááá°ááŹááťáŹá¸á á˝áŹáá˝ááş BPF ááᯠeBPF ááŻááŹá¸áááşááźááźáŽá¸ classical BPF ááᯠáááąáˇ cBPF ááŻááąáŤáşáááşá
eBPF áááş ááŻáśá áśáĄááťááŻá¸ááťááŻá¸ááźááˇáş classic BPF virtual machine ááᯠáááŻá¸ááťá˛áˇáááş-
- ááąááşáᎠ64-bit ááááŻááŹááťáŹá¸ááᯠáĄááźáąááśááŹá¸áááşá eBPF áááş 64-bit áážááşááŻáśáááşáážáŻááťáŹá¸ááᯠáĄááŻáśá¸ááźáŻááźáŽá¸ 2 (accumulator áážááˇáş X) ááž 10 áĄáá ááážááááŻááşááąáŹ áážááşááŻáśáááşáĄááąáĄáá˝ááşááᯠáááŻá¸ááąá¸ááŤáááşá eBPF áááş áááşááąáŹááşá¸ opcode ááťáŹá¸ (BPF_MOVá BPF_JNEá BPF_CALL...) ááᯠááąá¸ááŤáááşá
- áá˝ááşáááşáĄáá˝ážáŹáá˝á˛á áá áşááž áá˝á˛ááŻááşááŹá¸áááşá BPF áááş batch data model áážááˇáş ááťáááşáááşááŹá¸áááşá áááşá¸ááᯠpacket á á áşááŻááşááźááşá¸áĄáá˝ááş áĄááŻáśá¸ááźáŻááŹá¸ááąáŹááźáąáŹááˇáş áááşá¸áááŻááşáááş áá˝ááşáááşáááşáá˝ááşáážáŻááťáŹá¸ááᯠááśáˇáááŻá¸ááąá¸áááˇáş á áá áşáá˝á˛áá˝ááş áááşáážáááŤáááşá áááŻáˇááąáŹáşáááşá¸ eBPF virtual machine áááş data model áážááˇáş áááťáááşáááşááąáŹáˇáᲠáááşáááˇáşáááşáá˝ááşááťááşáĄáá˝ááşáááᯠáĄááŻáśá¸ááźáŻáááŻááşááŤáááşá áááŻáˇááźáąáŹááˇáşá ááᯠeBPF ááááŻááááşáĄáŹá¸ tracepoint áááŻáˇáááŻááş kprobe áááŻáˇ ááťáááşáááşáááŻááşááźáŽááźá áşáááşá áááşá¸áááş eBPF ááááááŹáááşááŹáááŹá á á˝ááşá¸ááąáŹááşáááşáá˝á˛ááźááşá¸á áááşááźáŹáážáŻáážááˇáş áĄááźáŹá¸ááąáŹ kernel áá˝á˛á áá áşááťáŹá¸á áááşá ááşáážáŻáá˝ááş áĄááźáŹá¸áĄááŻáśá¸ááźáŻáážáŻááá ášá áááşááťáŹá¸á á˝áŹáĄáá˝ááş áááşá¸áá˝ááˇáşááąá¸áááşá ááᯠeBPF ááŻááşáááş áááşá¸ááááŻááşáááŻááşáááşá¸ááźáąáŹááşá¸áá˝ááş áážáááąáááş- kernel/bpfá
- Maps ááŻááąáŤáşááąáŹ ááášááŹááŻáśá¸áááŻááşááŹááąááŹá áááŻá¸áááŻááşááťáŹá¸á Maps ááťáŹá¸áááş áĄááŻáśá¸ááźáŻáá°ááąááŹáážááˇáş kernel ááąááŹáááŻáˇáĄááźáŹá¸ ááąááŹááážááşáážáŻááᯠáá˝ááˇáşááąá¸áááˇáş ááąáŹáˇáááşáááŻá¸á áááŻá¸áááŻááşááťáŹá¸ááźá áşáááşá eBPF áááş ááźáąááŻáśáĄááťááŻá¸áĄá áŹá¸ááťáŹá¸á á˝áŹááᯠááąáŹááşááśáˇááąá¸áááşá
- áááˇáşáá˝áŹá¸ááŻááşááąáŹááşááťááşááťáŹá¸á áĄáá°á¸áááźááˇáşá áááşááąáˇááťáşáá áşááŻááᯠááźááşááąá¸áááşá checksum áá˝ááşááťááşáááş áááŻáˇáááŻááş áááşááąáˇááťáşáá áşááŻáá˝áŹá¸áááşá á¤ááŻááşááąáŹááşááťááşááťáŹá¸áááş kernel áĄáá˝ááşá¸áá˝ááşáĄááŻááşááŻááşááźáŽá¸ user-space ááááŻááááşááťáŹá¸áááŻááşááŤá eBPF ááááŻááááşááťáŹá¸ááž á áá áşááąáŤáşáááŻáážáŻááťáŹá¸áááşá¸ ááźáŻááŻááşáááŻááşáááşá
- ááąáŤáşáááŻáážáŻááťáŹá¸ááᯠáĄááŻáśá¸áááşááŤá eBPF áážá ááááŻááááşáĄáá˝ááşáĄá áŹá¸ááᯠ4096 bytes áááˇáşáááşááŹá¸áááşá áĄááźáŽá¸ááąáŤáşáááŻáážáŻáĄááşášááŤáááşáááş eBPF ááááŻááááşáĄáŹá¸ ááááşá¸ááťáŻááşáážáŻááᯠeBPF ááááŻááááşáĄáá áşáá áşááŻáááŻáˇ áá˝ážá˛ááźáąáŹááşá¸áááş áá˝ááˇáşááźáŻááŹá¸ááźáŽá¸ á¤áááˇáşáááşááťááşááᯠááťáąáŹáşáá˝ážáŹá¸áááŻááşáááş (á¤áááşá¸ááźááˇáş ááááŻááááş 32 ááŻáĄáá ááťáááşáááşáááŻááşáááş)á
eBPF: áĽáááŹ
Linux kernel áĄáááşá¸áĄááźá áşááťáŹá¸áá˝ááş eBPF áĄáá˝ááş áĽáááŹááťáŹá¸á á˝áŹáážááááşá áááşá¸áááŻáˇááᯠááá°ááŹ/bpf/ áá˝ááş ááážááááŻááşááŤáááşá á¤áĽáááŹááťáŹá¸ááᯠá áŻá ááşá¸áááşá áááŻá¸áážááşá¸á á˝áŹ áááˇáşáá˝ááşá¸ááŤ-
$ sudo make samples/bpf/
eBPF áĄáá˝ááş ááá°ááŹáĄáá
áşááᯠááťá˝ááşáŻááşáááŻááşáááŻááşááąá¸áááşáááŻááşááąáŹáşáááşá¸ samples/bpf/ áá˝ááş ááážááááŻááşááąáŹ ááá°ááŹááťáŹá¸áá˛ááž áá
áşááŻááᯠáĄááŻáśá¸ááźáŻááŤáááşá ááŻááşá áĄá
áááşáĄáááŻááşá¸áĄááťááŻáˇááᯠááźááˇáşáážáŻááźáŽá¸ áááşá¸áĄááŻááşááŻááşááŻáśááᯠáážááşá¸ááźááŤáááşá áĽáááŹáĄááąáá˛áˇá á፠program áááŻáá˝áąá¸ááťááşáá˛áˇáááşá tracex4
.
ááąááŻááťáĄáŹá¸ááźááˇáşá ááá°ááŹ/bpf/ áážá ááá°ááŹáá áşááŻá áŽáá˝ááş áááŻááşáážá áşáᯠááŤáááşáááşá ááŤáááŻáááş:
tracex4_kern.c
á áá˝ááş eBPF bytecode áĄááźá áş kernel áá˝ááş ááŻááşááąáŹááşááááˇáş áĄáááşá¸áĄááźá áşááŻááş ááŤáážááááşátracex4_user.c
áĄááŻáśá¸ááźáŻáá°ááąááŹáá˝ááşááž ááááŻááááşáá áşááŻááŤáážááááşá
ááŽááąááŹáážáŹááąáŹáˇ compile ááŻááşáááŻáˇáááŻáááşá tracex4_kern.c
eBPF bytecode áááŻáˇá ááąáŹááąáŹáááşáážáŹ gcc
eBPF áĄáá˝ááş backend ááážáááŤá ááśáĄáŹá¸ááťáąáŹáşá
á˝áŹá clang
eBPF bytecode ááŻááşááąá¸áááŻááşáááşá
áĄááŻáśá¸ááźáŻáážáŻ 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 áážááąá¸ááąáŹáááşáĄááťááŻá¸áĄá
áŹá¸ááťáŹá¸á
á˝áŹáá˛áážáá
áşááŻááźá
áşáááşá á¤ááá
ášá
áá˝ááşá áááşá¸áááş hash áá
áşááŻááťážááŹááźá
áşáááşá ááźáąáŹáşááźáŹáá
áşááŻáááŻáááşá¸ áááş áááááźáŻááááąáááşá 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;
}
á¤ááŻááşááąáŹááşááťááşáážá
áşááŻáááş áááˇáşáĄáŹá¸ ááźáąááŻáśááž entry áááŻááťááşáááşáá˝ááˇáşááźáŻáááş (kprobe/kmem_cache_free
) áážááˇáş ááźáąááŻáśáááŻáˇ áááşáá˝ááˇáşáĄáá
áşáá
áşáᯠáááˇáşá፠(kretprobe/kmem_cache_alloc_node
) á
áŹááŻáśá¸ááźáŽá¸ááťáŹá¸ááźááˇáş ááąá¸ááŹá¸ááŹá¸ááąáŹ ááŻááşááąáŹááşááťááşáĄáááşááťáŹá¸áĄáŹá¸ááŻáśá¸áááş áááşáážááşááŹá¸ááąáŹ áááşááááŻááťáŹá¸áážááˇáş áááşáááŻááşááŤáááşá
.
áĄááŹááášááŻáááŻááşá áĄáááŻááşá¸ááťáŹá¸ááᯠááŤá á˝ááˇáşáá áşááŤáá á¤ááášááĄáá áşááťáŹá¸ááᯠáááşáážááşááźáŽá¸ááźá áşááźáąáŹááşá¸ ááťá˝ááşáŻááşáá˝áąáˇááźááşááááş-
$ 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
áááşá¸áážááááşá
á áĄááááĄá
áŽáĄá
ááşá áĄááźáąááśáĄáŹá¸ááźááˇáşá á¤áĄá
áŽáĄá
ááşáááş áĄááźá
áşáĄááťááşááťáŹá¸ááᯠááŹá¸ááąáŹááşáááşá 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
function ááᯠáĄááŻáśá¸ááźáŻ 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;
}
ááŻááşááźááşá¸áĄáŹá¸ááźááˇáş
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 ááááŻááááşáááş áĄáááŻááşá¸áá
áşááŻáážááˇáş áááşá
ááşááąááąáŹ ááźáąááŻáśááťáŹá¸áážááˇáş ááŻááşááąáŹááşááťááşááťáŹá¸ááᯠáá˝á˛ááźáŹá¸áááşáážááşáááşá kernel áááş áĄááťááŻáˇááąáŹáĄááťááŻá¸áĄá
áŹá¸áá
áşááŻá ááźá
áşáááşáá
áşááŻááᯠááŻááşááźááąáŹáĄá፠(áĽáááŹá tracepoint
) ááŻááşááŻááşááŹá¸ááąáŹááŻááşááąáŹááşááťááşááťáŹá¸áááŻááŻááşááąáŹááşáááşá áááşááťáŹá¸áááş kernel ááááŻááááşáážááˇáş áĄááŻáśá¸ááźáŻáá°áĄáŹááŹáááááŻááááşáĄááźáŹá¸ áááşáá˝ááşáážáŻááᯠááąá¸áááşá
ááąáŹááşááťááş
á¤ááąáŹááşá¸ááŤá¸áá˝ááş BPF áážááˇáş eBPF áááŻáˇááᯠááąááŻááťáĄááŻáśá¸áĄáážáŻááşá¸ááťáŹá¸ááźááˇáş áá˝áąá¸áá˝áąá¸ááŹá¸áááşá áááąáˇ eBPF áážááˇáş áááşáááşááąáŹ áĄááťááşáĄáááşááťáŹá¸ áážááˇáş áĄáááşá¸áĄááźá áşááťáŹá¸á á˝áŹ áážááááşááᯠááťá˝ááşáŻááşááááŤáááşá áááŻáˇááźáąáŹááˇáş ááąáŹááşáááş ááąáˇááŹáááşáĄáá˝ááş áĄáááşá¸áĄááźá áşáĄáááşá¸áááşááᯠááťá˝ááşáŻááş áĄááźáśááźáŻááŤáááşá
áááşáááş áĄááźáśááźáŻáááŻááŤáááşá
BPF- universal in-kernel virtual machine Jonathan Corbett á BPF á ááááŤááşá¸áážááˇáş áááşá¸áááş eBPF áááŻáˇ ááźáąáŹááşá¸áá˛ááŹááŻáśáeBPF ááᯠá áąáˇá áąáˇá ááşá ááş ááááşáááşááźááşá¸á ááááşáááş ááááşááşá LWN.net áážááąáŹááşá¸ááŤá¸á Brendan áááş eBPF áĄááźáąáŹááşá¸ áááźáŹáá áá˝á áşááŹááŻááşááźáŽá¸ áá°áˇáĄááźáąáŹááşá¸áĄááŹáážááˇáşáááşáááşáááˇáş áĄáááşá¸áĄááźá áşá áŹáááşá¸ááᯠááááşá¸ááááşá¸ááŹá¸áááşááááąáŹáˇááş .BPF áážááˇáş eBPF áááŻááşáᏠáážááşá áŻááťáŹá¸ ááťá°ááŽááŹáĄáŽáááşá Suchakra Sharma áážáááşáááşáááˇáş âBSD Packet Filter- User-level Packet Capture áĄáá˝ááş ááááŻááŹáĄáá áşâá áážááşááťááşááťáŹá¸áááş ááąáŹááşá¸áá˝ááşááźáŽá¸ ááááŻááşááťáŹá¸ááᯠááŹá¸áááşáááş áĄáážááşááááş áá°ááŽááąá¸ááŤáááşáeBPFá áĄáááŻááşá¸ á- áĄááááşá áá ášá áŻáášáááşáážááˇáş áĄááŹáááş ááťáŹá¸áĄá˛áá áşá áážááşááťáŹá¸á á˝áŹáááşááŤááááşáááş ááŤááąáááˇáş áááşáááťááŻá¸áááşááŤáááşá eBPF áážáŹ áá˝áąáˇáá°á¸áááťáž áĄááąáŹááşá¸ááŻáśá¸ ááąáŹááşá¸ááŤá¸áá˝áąáá˛á áá áşááŻá
source: www.habr.com