Sadržaj

BPF tehnologija

Sažetak

BPF tehnologija originalno je razvijena u svrhu poboljšanja postojećih alata za primanje i analizu podataka mrežnog prometa. Prilagođavanjem na arhitekturu suvremenih procesora i proširenjem funkcionalnosti nastaje proširena BPF tehnologija (eBPF) koja je uključena u jezgru operacijskog sustava Linux. Posebna namjena eBPF tehnologije je pisanje mrežnih programa s mogućnošću filtracije i klasifikacije paketa. Dodatne mogućnosti koje eBPF pruža su mehanizam za jednostavno otkrivanje grešaka u komponentama jezgre i provođenje analize performansi.

BPF aplikacije izvršavaju se u korisničkom prostoru te s jezgrom komuniciraju putem BPF poziva. BPF pozivi osiguravaju siguran rad aplikacije i sprječavaju neželjeni utjecaj na jezgru ili sklopovlje. Prije prevođenja, BPF instrukcije prolaze kroz verifikaciju kako bi se osiguralo sigurno izvođenje BPF programa.

Najčešća primjena BPF alata je u analizi mrežnog podsustava. BPF alati pružaju informacije o pokrenutim TCP vezama, radu priključaka, broju odbijenih paketa, uzroku odbijanja paketa i slično. Neke od karakteristika datotečnog sustava koje se mogu pratiti BPF alatima su vijek trajanja datoteka, učestalost ulazno/izlaznih operacija nad datotekama i kašnjenje datotečnog sustava. BPF alati korisni su i u analizi rada procesora, pri čemu pružaju uvid u novonastale procese, vrijeme kašnjenja raspoređivača, uzroke prekida i slično.

Keywords: BPF; analiza performansi; Linux

Uvod

Berkeley Packet Filter (BPF) tehnologija početno je razvijena u svrhu poboljšanja rada alata za primanje i obradu paketa mrežnog prometa. Nakon značajnih promjena osnovne inačice, BPF tehnologija postaje napredan alat za analizu i filtriranje mrežnog prometa i kao takva uključena je u jezgru operacijskog sustava Linux.

Kako bi se iskoristile prednosti moderne arhitekture računala, uvedena je proširena BPF tehnologija - eBPF (engl. extended BPF). Pripadni instrukcijski set prilagođen je na procesore suvremenih računala, što znatno poboljšava performanse. Proširena BPF tehnologija bit će opisana u sljedećem poglavlju. Važno je napomenuti da nakon proširenja funkcionalnosti BPF prestaje biti skraćenica naziva alata za filtriranje, već naziv tehnologije. Pod nazivom BPF podrazumijeva se set instrukcija proširene BPF tehnologije.

BPF se sastoji od instrukcijskog seta, struktura podataka i pomoćnih funkcija. S obzirom da ima virtualni instrukcijski set, BPF se može smatrati virtualnim strojem. BPF arhitektura bit će detaljnije opisana u poglavlju Opis arhitekture.

Otkako je BPF tehnologija postala široko primjenjiva, razvijeni su mnogi alati za analizu različitih računalnih podsustava: procesora, memorije, datotečnih sustava, mreža, hypervisora i mnogih drugih. S obzirom da se BPF alati najčešće primjenjuju za analizu mrežnog prometa, poglavlje Primjena BPF alata bit će fokusirano na primjenu u mrežnom podsustavu, a bit će opisana i primjena u analizi rada procesora i datotečnog sustava. Izvorni kodovi svih opisanih alata mogu se pronaći u GitHub repozitoriju autora.

eBPF

Originalni BPF alat bio je dizajniran za dohvat i filtriranje mrežnih paketa koji su specificirani određenim pravilima. U početku se instrukcijski set BPF virtualnog stroja sastojao se od malog broja RISC instrukcija. Ovakav pristup nije mogao pratiti modernu arhitekturu procesora nakon prelaska na 64-bitnu arhitekturu. Uvođenjem eBPF dizajna iskorištene su prednosti moderne arhitekture. Virtualni stroj dizajniran je po uzoru na suvremene procesore te se eBPF instrukcije mogu mapirati tako da budu bliske instrukcijskom setu procesora. Kao najznačajnije promjene navodi se prelazak na 64-bitne registre i povećanje broja registara s dva na deset. Uvedena je i nova instrukcija za poziv funkcija, što omogućuje efikasniji poziv jezgrenih funkcija.

eBPF je posebno prilagođen za pisanje programa koji se vežu uz mrežni priključak, filtriraju i klasificiraju promet te prihvaćaju ili odbijaju pakete. Osim toga, eBPF je koristan za otkrivanje grešaka u komponentama jezgre i provođenje analize performansi. Programi se mogu povezati uz ispitne točke (tracepoints) i ispitivače (kprobes). S obzirom da eBPF programi mogu pristupati jezgrinim podatkovnim strukturama, moguće je razvijati i testirati nove programe bez potrebe za ponovnim prevođenjem jezgre.

Pored navedenog, eBPF implementira podatkovne strukture u svrhu prijenosa podataka između jezgre i korisničkog prostora – eBPF mape. Podaci se pohranjuju i dohvaćaju koristeći ključ. Postoji više različitih vrsta mapa s različitim karakteristikama: polje, tablica raspršenog adresiranja (hash tablica) i slično.

Sukladno promjeni naziva BPF tehnologije, u nastavku će se pod nazivom BPF podrazumijevati eBPF tehnologija.

Opis arhitekture

Donjom slikom prikazan je osnovni model operacijskog sustava. Korisničke aplikacije izvršavaju se u korisničkom načinu rada te putem sistemskih poziva komuniciraju s jezgrom koja predstavlja sučelje prema sklopovlju.

Uvođenjem BPF tehnologije u Linux jezgru nastao je novi model koji je prikazan sljedećom slikom. Ovaj model uveden je u operacijski sustav Linux 2014. godine.

Uvedeno je novo sučelje prema jezgri, BPF pozivi, koji su ekvivalent sistemskim pozivima kod korisničkih aplikacija. BPF pozivi omogućuju razvoj aplikacija koje se izvršavaju u jezgrenom načinu rada (engl. kernel-mode ), a komuniciraju s jezgrom kroz aplikacijsko programsko sučelje (API). BPF aplikacije imaju pristup svim resursima, izvode se s visokom učinkovitošću te garantiraju sigurnost.

Ovakav pristup razlikuje se od razvoja modula jezgre po tome što postoji fiksno aplikacijsko programsko sučelje koje osigurava siguran rad aplikacije i sprječava neželjeni utjecaj na jezgru ili sklopovlje. Drugim riječima, moguća je implementacija različitih servisa iz korisničkog prostora. Time je jezgrina funkcionalnost pomaknuta izvan jezgre, u korisnički prostor.

Osim promjene modela operacijskog sustava, uvođenjem BPF tehnologije mijenja se i model stanja procesa. Prema osnovnom modelu, korisnički ili jezgreni procesi mogu prelaziti iz blokiranog stanja u stanje izvođenja putem zamjene konteksta.

Model izvođenja BPF procesa jednostavniji je od osnovnog jer su BPF aplikacije upravljane događajima (engl. event-driven). U ovom slučaju nema zamjene konteksta ni raspoređivača zadataka – BPF program neprekinuto se izvršava do završetka.

Model sustava koji ilustrira rad BPF aplikacija upravljanih događajima prikazan je sljedećom slikom.

BPF instrukcije izvršava posrednički proces Linux jezgre koji obavlja prevođenje virtualnih instrukcija u izvorne instrukcije. Prije prevođenja, BPF instrukcije potrebno je verificirati kako bi se osiguralo sigurno izvođenje BPF programa. Prvi korak verifikacije osigurava da će BPF program završiti i da ne sadrži petlje koje bi zaustavile rad jezgre. U drugom se koraku simulira izvođenje programa instrukciju po instrukciju. Nakon svakog koraka provjerava se stanje registara i stoga pri čemu su zabranjeni skokovi izvan granica i pristup podacima izvan dosega. Instrukcije se prevode u strojni kod pomoću interpretera i JIT prevoditelja (engl. Just-In-Time Compiler).

U sljedećoj tablici rezimirane su karakteristike BPF programa i dana je usporedba s korisničkim i jezgrinim programima.

Korisničke aplikacijeJezgrine aplikacijeBPF aplikacije
Model izvršavanjazadacizadacidogađaji
Korisnički definiranodaneda
PrevođenjeJIT ili statičkistatičkiJIT
Sigurnostmaksimalna/verifikacija instrukcija
Pristup resursimasistemski pozividirektnoBPF pozivi (ograničeno)

Primjena BPF tehnologije

Primjena u analizi datotečnog sustava

S obzirom da aplikacije najčešće imaju direktnu interakciju s datotečnim sustavom, ovaj podsustav vrlo je važan za analizu. BPF alati za analizu datotečnog sustava omogućuju praćenje vremena koje je aplikacija provela čekajući na ulazno/izlazne operacije, detekciju procesa koji su odgovorni za te operacije te uvid u popis datoteka nad kojima su se izvršavale operacije.

Tradicionalni alati za analizu datotečnog sustava uglavnom se fokusiraju na performanse ulazno/izlaznih operacija. Da bi se upotpunila ova funkcionalnost, BPF alati donose mogućnost analize provedenih operacija i internih funkcija svakog datotečnog sustava. Pregled alata po pripadnim slojevima prikazan je na sljedećoj slici.

opensnoop

Alat opensnoop prati operacije otvaranja datoteka (sistemski poziv open ) i koristan je za otkrivanje podatkovnih i konfiguraicijskih datoteka te dnevnika. Moguće je otkriti i probleme uzrokovane učestalim otvaranjem datoteka. U nastavku je naveden primjer korištenja naredbe. U ispisu se može uočiti utjecaj naredbe ispis datoteke (cat ) na testnu datoteku.

$ sudo ./opensnoop.bt 
Attaching 6 probes... 
Tracing open syscalls... Hit Ctrl-C to end. 
^C 
PID    COMM               FD ERR PATH 
3515   DeviceManager      38   0 /sys/bus/usb/devices 
22406  cat                 3   0 filetest 

scread

Pomoću alata scread moguće je pratiti operacije čitanja datoteka (sistemski poziv read ). Ime datoteke dohvaća se iz tablice deskriptora datoteka.

$ sudo ./scread.bt  
Attaching 1 probe... 
^C 
@filename[eventfd]: 6 
@filename[2]: 18 
@filename[null]: 84 
@filename[UNIX]: 705 

filelife

Alat filelife služi za utvrđivanje vijeka trajanja datoteka za datoteke koje su stvorene tijekom praćenja. Ispisuje vrijeme proteklo od stvaranja datoteke do brisanja. Radi ilustracije u primjeru je naveden dio ispisa alata filelife tijekom prevođenja Linux jezgre. U ispisu se mogu uočiti privremene datoteke koje generira prevoditelj gcc.

$ sudo ./filelife.bt 
Attaching 4 probes... 
PID    COMM              AGE(ms) FILE 
13761  collect2               15 cckGcMec.o 
13758  gcc                    16 ccRVpLCe.res 
13758  gcc                    21 ccqWu0qc.o 
13758  gcc                    35 cc4bYSfa.s 
13763  rm                     15 a.out 

Ostali BPF alati vezani uz datotečni sustav koriste se za analizu statistike operacija virtualnog datotečnog sustava, stranica priručne memorije, brzine rada operacija čitanja i pisanja, praćenje montiranih datotečnih sustava i mnogih drugih karakteristika.

U nastavku su navedeni uobičajeni koraci analize datotečnog sustava:

1. identifikacija montirane datotečne sustave (naredba df i mount)

2. provjera kapaciteta montiranih datotečnih sustava

3. kreirati testno okruženje s poznatim opterećenjem datotečnog sustava – naredbom fio moguće je specificirati određeni broj dretvi i procesa koji obavljaju određenu ulazno/izlaznu operaciju nad datotečnim sustavom

4. pokrenuti alat opensnoop kako bi se utvrdilo koje su datoteke otvorene

5. pokrenuti alat filelife radi provjere postoje li datoteke s kratkoročnom upotrebom

6. ispitati brzinu rada datotečnog sustava i utvrditi detalje o aktivnim procesima i datotekama (primjerice alat ext4slower)

7. ispitati raspodjelu latencije datotečnog sustava (alat ext4dist)

8. utvrditi udio pogodaka priručne memorije (alat cachestat)

9. usporediti brzinu logičkih i fizičkih ulazno/izlaznih operacija alatom vfsstat (pod pretpostavkom da je korištenje priručne memorije učinkovito, logičke operacije su očekivano brže).

Primjena u analizi rada procesora

Procesori predstavljaju početnu točku za analizu performansi računalnog sustava. Uobičajeni alati (primjerice top i perf ) pokazuju iskorištenost procesora po pojedinom procesu, brzinu zamjene konteksta i slično. Analiza pomoću BPF alata daje mnogo više detalja, uključujući popis novonastalih procesa i vremena njihovog trajanja, koliko dugo dretve zauzimaju procesor, koliko čekaju u redu izvođenja, koji prekidi se javljaju i slično. Alati se oslanjaju na praćenje raspoređivača zadataka i događaja uslijed sistemskih poziva. Pregled BPF alata vezanih uz rad procesora prikazan je sljedećom slikom.

execsnoop

Alat execsnoop prati izvođenje novih procesa, a koristan je za detekciju kratkotrajnih procesa koje je teško uočiti korištenjem alata kao što je top . U nastavku je naveden dio ispisa alata execsnoop pri pokretanju programskog okruženja Xilinx Vivado.

$ sudo ./execsnoop.bt  
Attaching 2 probes... 
TIME    PID    ARGS
22114   16594  /opt/Xilinx/Vivado/2018.3/bin/vivado
21983   15494  /opt/Xilinx/Vivado/2018.3/bin/loader -exec vivado

runqlat

Alat runqlat služi za mjerenje latencije raspoređivača. Ova karakteristika korisna je za definiranje zasićenja procesora, stanja u kojem ima više zahtjeva za resursima nego što se može obraditi. Kao što je vidljivo u primjeru, rezultat naredbe je histogram koji pokazuje koliko vremena dretve provedu u stanju čekanja. U ovom slučaju, dretve većinu vremena čekaju između 16 i 126 mikrosekundi.

$ sudo ./runqlat.bt 
Attaching 5 probes...
Tracing CPU scheduler... Hit Ctrl-C to end.
^C


@usecs: 
[2, 4)                11 |                                                    |
[4, 8)                38 |@@                                                  |
[8, 16)              169 |@@@@@@@@@@                                          |
[16, 32)             793 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    |
[32, 64)             409 |@@@@@@@@@@@@@@@@@@@@@@@@                            |
[64, 128)            855 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|
[128, 256)           268 |@@@@@@@@@@@@@@@@                                    |
[256, 512)           183 |@@@@@@@@@@@                                         |
[512, 1K)              9 |                                                    |
[1K, 2K)               6 |                                                    |

Primjena u analizi mrežnog prometa

Mrežni promet odvija se putem različitih slojeva i protokola, uključujući aplikacijski sloj, sistemske pozive, protokole TCP ili UDP i IP te upravljačke programe za mrežno sučelje. Rad svake navedene komponente može se pratiti pomoću alata koje pruža BPF. Tradicionalni alati za analizu mrežnog prometa oslanjaju se na dohvat paketa. BPF alati pružaju detaljnije informacije te daju odgovore na sljedeća pitanja:


Pregled BPF alata uz pripadne slojeve prikazan je na donjoj slici, a u nastavku će ukratko biti opisani najvažniji alati.

sockstat

Pomoću alata sockstat moguće je ispisati statistiku priključaka uz broj sistemskih poziva vezanih uz priključke. Ispis se ponavlja za svaku proteklu sekundu. U ovom primjeru vidljivi su sistemski pozivi sock_sendmsg() i sock_recvmsg() .

Ovaj alat pruža uvid u statistiku priključaka na visokoj razini i koristan je za pokretanje daljnje analize. U ispis je uključen i naziv ispitivača (engl. probe) kako bi se olakšala analiza. Primjerice, ako je uočen prevelik broj kprobe:sock_sendmsg() događaja, proces se može dohvatiti pomoću sljedeće naredbe:

$ sudo ./sockstat.bt 
Attaching 10 probes... 
Tracing sock statistics. Output every 1 second. 
23:16:16 
@[kprobe:sock_sendmsg]: 99 
@[kprobe:sock_recvmsg]: 1421 

sofamily

Alat sofamily omogućuje praćenje novih povezivanja na priključke putem sistemskih poziva accept i connect . Također, navodi se naziv procesa i obitelj adresa (IPv4 ili IPv6). Alat je koristan za detekciju neočekivane uporabe priključaka. U nastavku je naveden primjer korištenja ovog alata.

$ sudo ./sofamily.bt 
Attaching 7 probes... 
Tracing socket connect/accepts. Ctrl-C to end. 
^C 
@connect[DNS Res~er #673, 2, AF_INET]: 1 
@connect[systemd-resolve, 10, AF_INET6]: 15 

U uglatim zagradama je navedeno redom: ime procesa, broj obitelji adresa te ime obitelji adresa, ukoliko je poznata. Ovakvo mapiranje brojeva adresnih obitelji specifično je za Linux i definirano je u zaglavlju include/linux/socket.h . U ovom primjeru je tijekom pokretanja alata bio aktivan web preglednik, stoga su vidljivi DNS zahtjevi.

soprotocol

Pomoću alata soprotocol također je moguće pratiti nova povezivanja na priključke, ali osim naziva procesa navodi se i protokol koji je korišten.

socketio

Alat socektio omogućuje ispis količine ulazno/izlaznih transakcija na priključcima. Također, ispisuje se količina prenesenih podataka po pojedinom procesu i smjeru.

U ovom primjeru proces systemd-resolve , PID 706, obavio je 10 pisanja s ukupno 364 okteta podataka. Podaci o čitanju i pisanju dobivaju se praćenjem jezgrenih funkcija sock_read_iter() i sock_write_iter() koje spadaju u file_operations strukturu koja pripada pojedinom priključku.

$ sudo ./socketio.bt 
Attaching 5 probes... 
^C 
@bytes[nautilus, 6733, write, UNIX]: 16 
@bytes[systemd-resolve, 706, write, UDP]: 364 
@bytes[firefox, 9166, write, UNIX]: 10784 
@bytes[gnome-terminal-, 31258, write, UNIX]: 54952 
@io[nautilus, 6733, write, UNIX]: 1 
@io[systemd-resolve, 706, write, UDP]: 10 
@io[firefox, 9166, write, UNIX]: 631 
@io[gnome-terminal-, 31258, write, UNIX]: 77 

Zaključak

S porastom zahtjeva na brzinu i sigurnost računala, otvaraju se mnoga i daleko opsežnija područja primjene BPF tehnologije. Kao nova vrsta programske potpore, BPF pruža mogućnost skaliranja i unaprjeđivanja postojećih alata za analizu performansi raznih komponenata sustava, ali i implementaciju novih komponenata. Osim u efikasnosti, snaga tehnologije je i u sigurnosti koju osiguravaju opisane karakteristike. Ova tehnologija posebno je od interesa web-sjedištima jer pruža zaštitu od mrežnih napada. Primjerice, na svakom poslužitelju kompanije Facebook izvršava se oko 40 aktivnih BPF aplikacija.

Literatura

[1] Gregg, B. BPF Performance Tools. Addison-Wesley, 2019.

[2] Fleming, M. A thorough introduction to eBPF. 2017.

[3] Brendan Gregg's Blog

[4] Corbet, J. A JIT for packet filters. 2011.

[5] Corbet, J. BPF: what's good, what's coming, and what's needed. 2019.