100 m pakietów na sekundę dla każdego
TRANSCRIPT
100 mln pakietów na sekundę dla każdego
ICWAT 2015.11.12
Paweł Małachowski Michał Mirosław
2
Multimedia Smart Grid
Cyberbezpieczeństwo
Phoenix-RTOS Phoenix-PRIME
Hermes
Grupa Kapitałowa Atende Software
Wybrani klienci
http://antyweb.pl/odwiedzilismy-atende-software-to-dzieki-nim-mozecie-ogladac-iple-i-player-pl/
Szybko, szybciej…
Skąd taki temat?
5
Obecnie rozwijamy usługę redGuardian (anty DDoS) i chcemy przybliżyć Wam zagadnienie wydajnej obsługi ruchu IP na platformie klasy PC.
Obsługa to routing, firewalling, load balancing, deep packet inspection (DPI, IDS/IPS)…
… bez akceleracji aplikacji, bo to mógłby być osobny temat.
100 milionów? Ale pakietów…
Nasze realia:
• Ethernet 1 Gbit/s jest standardem
• Porty 10 Gbit/s on-board w serwerach stają się coraz popularniejsze
• 40 Gbit/s i 100 Gbit/s – na razie głównie w sieci szkieletowej
6
Policzmy: • Miary: bps vs. pps • 10 Gbit/s to inaczej
• 0,81 Mpps przy ramkach 1500B • ~14,88 Mpps przy małych ramkach (64B + 20B luka i preambuła)
• Zatem 100 Mpps wymaga minimum 7 x 10G
Wydajna obsługa sieci vs. współczesny sprzęt klasy PC
• CPU i magistrala – PCI Express 3.x: ~985 MB/s każda na linię
– współczesny Xeon na LGA 2011 ma 40 linii PCIe 3.0 czyli ~39GB/s (~315Gbit/s)
– uwaga na narzut magistrali
– a przecież można kupić płytę 2 x CPU
– do tego nawet 45MB cache L3
– Intel DDIO
• Pamięć operacyjna – DDR4, np. PC-2133, 4 kanały po ~17GB/s
• Karty sieciowe – bogata oferta Intel, Broadcom, Chelsio, Mellanox, Solarflare i innych
– sprzętowe wsparcie hashowania pakietów do wielu kolejek
– 1 x 10Gbit/s, 2 x 10Gbit/s, 4 x 10Gbit/s, 1 x 40Gbit/s, 2 x 40Gbit/s (oszukane)
– 100Gbit/s – nisza, ale wszystko jest kwestią czasu (i PCIe 4.x)
7
Już dziś serwer zdolny obsłużyć 200 Gbit/s jest w zasięgu ręki: kilkanaście tys. PLN na PC + kilka tys. PLN na karty sieciowe.
Nasz LAB
8
Osiągi: oczekiwania kontra rzeczywistość
• aplikacyjny flooder:
– ~100-200 kpps per core
– ale z pomijaniem qdisc: ~1 Mpps per core
• in-kernel pktgen: ~5 Mpps per core
• prosty aplikacyjny sender+receiver:
– UDP lub HTTP z minimalnym responsem
– ~200-500 kpps per core
– trudne strojenie
• realnie z całej maszyny ciężko wyjść ponad kilka Mpps na prostej aplikacji
9
źródła: • badania własne • https://blog.cloudflare.com/how-to-receive-a-million-packets/
Skomplikowany świat kernela: podsystemy
Sterownik NIC
Abstrakcja urządzenia
Warstwa 2
Bridge
Routing
Firewall
Kolejkowanie
Gniazda dla aplikacji
10
źródło: https://upload.wikimedia.org/wikipedia/commons/5/5b/Linux_kernel_map.png
Skomplikowany świat kernela: obsługa sieci
11
źródło: http://www.linuxfoundation.org/images/1/1c/Network_data_flow_through_kernel.png
Szybko, szybciej… a tu ściana. Co można z tym zrobić?
Budżet mocy vs. koszty przetwarzania
• Aby uzyskać 14,8 Mpps potrzebujemy:
– 1277 ns na duży pakiet
– ~67,2 ns na mały pakiet
• daje to w uproszczeniu (pomijając zrównoleglanie) około 200 cykli współczesnego 3GHz CPU
• Dla porównania:
– L2 cache: ~4 ns
– L3 cache: ~8 ns
– atomic lock+unlock: 16 ns
– cache miss: ~32ns
– syscall: 50–100 ns (uwaga na wpływ SELinux)
Źródła:
• „Network stack challenges at increasing speeds. The 100Gbit/s challenge”, RedHat 2015
• „HOW TO TEST 10 GIGABIT ETHERNET PERFORMANCE”, Spirent Whitepaper, 2012
13
Co robić, jak żyć?
Najlepiej:
• nie sięgać do pamięci operacyjnej, tylko do CPU cache – prefetching
– małe struktury danych
• unikanie locków, struktury danych per core i lock-free
• NUMA awareness, CPU pinning
• minimalizowanie syscalli, brak context switchy
Ponadto:
• batchowanie pakietów
• polling zamiast przerwań
• kilka rdzeni CPU na port
• brak kopiowania danych (zero copy)
• prealokacja całej pamięci, huge pages (TLB friendly)
14
Kernel: panu już dziękujemy
• bezpośrednia obsługa karty sieciowej przez proces w userspace – PCI UIO
– sterowniki dla różnych kart
– współdzielenie karty z systemem
• brak stosu sieciowego – tracimy firewall, kolejkowanie, TCP/IP socket API dla aplikacji
– dostajemy surowe ramki i wszystko robimy „na piechotę” (packet forwarding, firewalling, sniffing itp.)
15
Userland dataplane – wybrane implementacje
• DPDK
– C, licencja BSD
– własne sterowniki
• Netmap
– C, licencja BSD
– zmodyfikowany sterownik jądra
• PF_RING ZC
– C, licencja LGPL (ale: licencjonowany moduł zero–copy)
– zmodyfikowany sterownik jądra
• Snabb switch
– LuaJIT, licencja Apache
– własne sterowniki
16
Case study
JAK ŁATWO ZEPSUĆ WYDAJNOŚĆ
na przykładzie policera
ZADANIE
18
• ograniczenie przepustowości (rate limiting, policing)
• bez kolejkowania pakietów
ZADANIE – LAB
19
WARUNKI LAB
• 4 – core 3 GHz
• 4 x 10GE
• 10GE / 64B ≈ 14,88 Mpps
• ~200 cykli/pakiet
• RX/TX: -100 cykli/pakiet
» 100 cykli?
DAMY RADĘ!
20
ALGORYTM
21
ALGORYTM
22
IMPLEMENTACJA #1
; %rsi = pktbuf, %rdi = policer_state
loop: RX...
movl bucket(%rdi), %eax
subl len(%rsi), %eax
jb loop ; drop
movl %eax, bucket(%rdi)
TX...
jmp loop
23
IMPLEMENTACJA #1 - SYMULACJA
*******************************************************************
Intel(R) Architecture Code Analyzer Mark Number 1
*******************************************************************
Throughput Analysis Report
--------------------------
Block Throughput: 1.00 Cycles
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | |
---------------------------------------------------------------------------------
| 0* | | | | | | | | | | nop
| 1 | | | 1.0 1.0 | | | | | | CP | mov eax, dword ptr [rdi]
| 2^ | 0.5 | | | 1.0 1.0 | | | 0.5 | | CP | sub eax, dword ptr [rsi]
| 0F | | | | | | | | | | jb 0xfffffffffffffffb
| 2^ | | | | | 1.0 | | | 1.0 | CP | mov dword ptr [rdi], eax
Total Num Of Uops: 5
24
MULTI–CORE
CORE 1_ CORE 2_
movl bucket(%rdi), %eax ...
subl len(%rsi), %eax movl bucket(%rdi), %eax
jb loop ; drop subl len(%rsi), %eax
movl %eax, bucket(%rdi) jb loop ; drop
... movl %eax, bucket(%rdi)
25
MULTI–CORE
CORE 1_ CORE 2_
movl bucket(%rdi), %eax ...
subl len(%rsi), %eax movl bucket(%rdi), %eax
jb loop ; drop subl len(%rsi), %eax
movl %eax, bucket(%rdi) jb loop ; drop
... movl %eax, bucket(%rdi)
2 pakiety zamiast 1!
26
IMPLEMENTACJA #2
; %rsi = pktbuf, %rdi = policer_state
loop: RX...
movl bucket(%rdi), %eax
redo: movl %eax, %edx
subl len(%rsi), %edx
jb loop ; drop
lock cmpxchg %edx, bucket(%rdi)
jnz redo
TX...
jmp loop
27
IMPLEMENTACJA #2 - SYMULACJA
*******************************************************************
Intel(R) Architecture Code Analyzer Mark Number 2
*******************************************************************
Throughput Analysis Report
--------------------------
Block Throughput: 2.00 Cycles
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | |
---------------------------------------------------------------------------------
| 0* | | | | | | | | | | nop
| 1 | | | 0.5 0.5 | 0.5 0.5 | | | | | | mov eax, dword ptr [rdi]
| 0* | | | | | | | | | | mov edx, eax
| 2^ | 0.6 | | 0.5 0.5 | 0.5 0.5 | | | 0.3 | | | sub eax, dword ptr [rsi]
| 0F | | | | | | | | | | jb 0xfffffffffffffff9
| 4^ | 0.2 | 1.2 | 0.5 0.5 | 0.5 0.5 | | 1.2 | 0.3 | | | lock cmpxchg [rdi], edx
| 1 | 0.4 | | | | | | 0.6 | | | jnz 0xfffffffffffffff6
Total Num Of Uops: 8
28
IMPLEMENTACJA #2 – SMOKE TEST
• 1 core → 10 Gbps DZIAŁA!
• 2 core → 19 Gbps (to na pewno źle generator liczy)
• 4 core → 15 Gbps … ???
29
IMPLEMENTACJA #3
; %rsi = pktbuf, %rdi = policer_state
loop: RX...
movl bucket(%rdi), %eax
movl len(%rsi), %edx
subl %edx, %eax
js loop ; drop
lock subl %edx, bucket(%rdi)
TX...
jmp loop
30
IMPLEMENTACJA #3 - SYMULACJA
*******************************************************************
Intel(R) Architecture Code Analyzer Mark Number 3
*******************************************************************
Throughput Analysis Report
--------------------------
Block Throughput: 1.50 Cycles
| Num Of | Ports pressure in cycles | |
| Uops | 0 - DV | 1 | 2 - D | 3 - D | 4 | 5 | 6 | 7 | |
---------------------------------------------------------------------------------
| 0* | | | | | | | | | | nop
| 1 | | | 0.5 0.5 | 0.5 0.5 | | | | | CP | mov eax, dword ptr [rdi]
| 1 | | | 0.5 0.5 | 0.5 0.5 | | | | | CP | mov edx, dword ptr [rsi]
| 1 | 0.5 | | | | | | 0.5 | | | sub eax, edx
| 0F | | | | | | | | | | js 0xfffffffffffffff9
| 4^ | | 0.5 | 0.5 0.5 | 0.5 0.5 | 1.0 | 0.5 | | 1.0 | CP | lock sub [rdi], edx
Total Num Of Uops: 7
31
IMPLEMENTACJA #3 – SMOKE TEST
• 1 core → 10 Gbps
• 2 core → 20 Gbps (a może jednak generator dobrze liczy?)
• 4 core → 25 Gbps
SKUCHA :-( 32
KONKURENCJA SMP
33
KONKURENCJA SMP
34
KONKURENCJA SMP
35
IMPLEMENTACJA #4 – POWRÓT DO POCZĄTKU
; %rsi = pktbuf, %rdi = policer_state
loop: RX...
movl bucket(%rdi), %eax
subl len(%rsi), %eax
jb loop ; drop
movl %eax, bucket(%rdi)
TX...
jmp loop
36
PO ¼ WIADERKA PER CORE
IMPLEMENTACJA #4 – SMOKE TEST
• 1 core → 10 Gbps
• 2 core → 20 Gbps
• 4 core → 40 Gbps
TAK MIAŁO BYĆ!
37
IMPLEMENTACJA #4 – CO DALEJ?
• Nie zadziała poprawnie przy nierównym podziale ruchu – Musimy dynamicznie zmieniać podział
• Policerów potrzeba więcej niż jeden – Nie możemy zmieniać wszystkich za każdym razem
• Potrzebujemy statystyk – Dodatkowe obciążenie CPU cache
38
cdn.
Co nas czeka? Perspektywy rozwoju tej dziedziny
1. NFV: wydajniejsze wirtualne appliance (firewall, load balancer, NAT) w postaci obrazów VM, które osiągają wydajność zbliżoną do sprzętu
2. Zwiększanie wydajności obsługi sieci w hypervisorach i ich wirtualnych sieciach (zero copy)
3. Optymalizacje stosu sieciowego w systemach operacyjnych (zapożyczanie technik)
4. Integracja z systemami operacyjnymi OOTB, np.
1. przyspieszenie firewalli
2. stos TCP/IP w userland, dołączany per proces
5. Sukcesywne wypieranie rozwiązań sprzętowych
6. Wzrost znaczenia otwartych architektur sprzętu sieciowego
39
Czytali
Paweł Małachowski
40
Michał Mirosław
Atende Software sp. z o.o. Dział Systemów Bezpieczeństwa
Dziękujemy za uwagę!
http://atendesoftware.pl/career/aboutus