\subsubsection{Performance-Vergleich} \paragraph{Testaufbau} Um die Performance der beiden Firewall-Lösungen vergleichen zu könne, habe ich jeweils zwei unserer Zotac-Boards mit der Onboard-Netzwerkkarte an einen zusätzlichen Firewall-Rechner, der mir bereitgestellt wurde, verbunden. Die Spezifikationen der Zotac-Boards sind dem Abschnitt »Hardware« zu entnehmen. \\ Der zusätzliche Rechner war mit einem Intel Core 2 Duo E6750 mit 2,66 GHz, 2 GiB RAM ausgestattet und zwei Intel Gigabit-Netzwerkkarten ausgestattet (Intel 82566DM-2 und 82572EI). Die beiden Intel-Netzwerkkarten wurden direkt mit den beiden Zotac-Boards verbunden. Der Firewall-Rechner wurde über die Onboard-Netzwerkkarte und die beiden Zotac-Boards über USB-Netzwerkkarten mit einem Switch und darüber mit der Headnode verbunden um einen Zugriff von außen bereitzustellen. \\ Der Firewall-Rechner soll nun über \texttt{iptables} und \texttt{nftables} den Datenverkehr zwischen den beiden Nodes kontrollieren. Die beiden Netzwerk-Interfaces der Firewall waren im Bridge-Modus verbunden. \\ \includegraphics{bilder/nft-layout.pdf} \paragraph{Verwendete Software} Um schnell genug eine große Anzahl an Paketen pro Sekunde (PPS) erzeugen zu können um die Firewall-Lösungen zu benchmarken, habe ich \texttt{pktgen} verwendet. Hierbei handelt es sich um einen Paketgenerator, der als Kernel-Modul geladen wird und dadurch direkt im Kernel (ohne teure Kontext-Switches ins Userland) ausgeführt wird. Zur Überwachung der Messdaten (Datenrate und PPS) habe ich auf allen vier Netzwerkschnittstellen das Tool \texttt{ifpps} aus dem \texttt{netsniff-ng}-Bundle laufen lassen. \pagebreak \paragraph{Testeinstellung} Zunächst habe ich die Datenrate und die PPS in Abhängigkeit der Ethernet Frame-Größe gemessen um festzustellen, mit welcher Paketgröße die Messungen am besten durchzuführen sind. \\ \\ \pgfplotstableread{ size rate pps 1500 986.004 82167 1450 985.7216 84976 1400 984.7376 87923 1350 984.2904 91138 1300 983.4968 94567 1250 982.78 98278 1200 982.08 102300 1150 981.18 106650 1100 980.2496 111392 1050 979.2384 116576 1000 978.304 122288 950 977.36 128600 900 975.0024 135417 850 974.27 143275 800 972.5888 151967 750 970.572 161762 700 968.3856 172926 650 966.2328 185814 600 963.1056 200647 550 959.7588 218127 500 955.604 238901 450 951.588 264330 400 945.3248 295414 350 937.3336 334762 300 923.2584 384691 250 855.588 427794 200 662.5952 433335 150 527.3604 439467 100 354.96 443700 50 207.176 446500 }\sizeratepps \begin{tikzpicture} \pgfplotsset{ y axis style/.style={ yticklabel style=#1, y axis line style=#1, ylabel style=#1, ytick style=#1 } } \begin{axis}[ width=15cm, height=10cm, title=Sender, xmin=1, xmax=1500, xlabel={Ethernet Frame-Größe}, xtick={100,300,500,700,900,1100,1300,1500}, ymin=0, axis y line*=left, ylabel={Datenrate [MBit/s]}, y axis style=blue!75!black, tick label style={/pgf/number format/fixed,/pgf/number format/1000 sep = \thinspace}, scaled ticks=false ] \addplot[smooth,blue] table[x={size}, y={rate}] {\sizeratepps}; \end{axis} \begin{axis}[ width=15cm, height=10cm, xmin=1, xmax=1500, axis x line=none, ymin=0,ymax=500000, ytick pos=right, axis y line* = right, ylabel={PPS}, ylabel near ticks, ytick={100000,200000,300000,400000}, y axis style=red!75!black, tick label style={/pgf/number format/fixed,/pgf/number format/1000 sep = \thinspace}, scaled ticks=false ] \addplot[smooth,red] table[x={size}, y={pps}] {\sizeratepps}; \end{axis} \end{tikzpicture} \vspace{1cm} \pgfplotstableread{ size rate pps 1500 982.38 81865 1450 981.1512 84582 1400 983.4272 87806 1350 981.936 90920 1300 979.9816 94229 1250 977.44 97744 1200 980.7936 102166 1150 978.5396 106363 1100 975.6472 110869 1050 972.3588 115757 1000 977.192 122149 950 974.0312 128162 900 970.6896 134818 850 965.4368 141976 800 970.8992 151703 750 966.756 161126 700 960.9544 171599 650 956.2592 183896 600 961.4736 200307 550 954.8088 217002 500 946.992 236748 450 928.7784 257994 400 823.2672 257271 350 722.5316 258047 300 615.1632 256318 250 492.206 246103 200 406.3824 253989 150 299.2116 249343 100 205.8888 257361 50 123.79728 257911 }\sizerateppsrecv \begin{tikzpicture} \pgfplotsset{ y axis style/.style={ yticklabel style=#1, y axis line style=#1, ylabel style=#1, ytick style=#1 } } \begin{axis}[ width=15cm, height=10cm, title=Empfänger, xmin=1, xmax=1500, xlabel={Ethernet Frame-Größe}, xtick={100,300,500,700,900,1100,1300,1500}, ymin=0, axis y line*=left, ylabel={Datenrate [MBit/s]}, y axis style=blue!75!black, tick label style={/pgf/number format/fixed,/pgf/number format/1000 sep = \thinspace}, scaled ticks=false ] \addplot[smooth,blue] table[x={size}, y={rate}] {\sizerateppsrecv}; \end{axis} \begin{axis}[ width=15cm, height=10cm, xmin=1, xmax=1500, axis x line=none, ymin=0,ymax=500000, ytick pos=right, axis y line* = right, ylabel={PPS}, ylabel near ticks, ytick={100000,200000,300000,400000}, y axis style=red!75!black, tick label style={/pgf/number format/fixed,/pgf/number format/1000 sep = \thinspace}, scaled ticks=false ] \addplot[smooth,red] table[x={size}, y={pps}] {\sizerateppsrecv}; \end{axis} \end{tikzpicture} \pagebreak Wie aus den Diagrammen ersichtlich wird, wird bei Frame-Größen, die an die MTU des Ethernets (1500 Bytes) heranreichen, das Gigabit-Netzwerk mit ca. 980 MBit/s und ca. 82000 PPS fast komplett ausgereizt. Je kleiner die Frame-Größe wird, desto größer wird zunächst die Anzahl der PPS, da das Netzwerk immer noch gut ausgelastet wird; die Datenrate sinkt zunächst zur langsam. \\ Beim Sender beginnt jedoch bei Frame-Größe kleiner 300 Byte die Datenrate linear zu sinken. Die PPS stagnieren dann bei ca. 450000 Paketen. Dies ist mit der Leistungsfähigkeit der Atom-Prozessoren zu erklären, da diese ab dieser Grenze komplett ausgelastet sind und die Pakete nicht schneller erzeugen können. \\ Beim Empfänger geschieht dieser Einbrauch schon bei ca. 450 Byte Frame-Größe. Hier stagniert die PPS bei ca. 250000. Auch dies lässt sich mit der Auslastung des Prozessors erklären. Der Unterschied zum Sender besteht darin, dass bei diesem die Pakete lediglich statisch zusammengesetzt und losgeschickt werden müssen. Beim Empfänger hingegen muss das Betriebssystem die Pakete zunächst auswerten, was den Bearbeitungszeit verlängert. Dadurch kommen beim Empfänger wesentlich weniger Pakete an, als der Sender losschickt. (Die übrigen Pakete werden gedroppt.) \\ Um eine größtmögliche Auslastung des Gigabit-Netzwerkes zu ermöglichen und gleichzeitig die maximale Anzahl an PPS zu erhalten, habe ich also für die folgenden Benchmarks die Ethernet Frame-Größe auf 450 festgesetzt. \paragraph{Anfängliche Probleme} Anfangs habe ich auf dem Empfänger keine »Anwendung« laufen lassen, die die Pakete des Senders entgegennimmt. Deshalb musste der Kernel zusätzliche ein ICMP-Paket mit »Connection Refused«-Flag an den Sender zurückschicken und daraufhin weitere Fehlerbehandlungen durchführen. Auf diese Weise habe ich am Empfänger zunächst nur ca. 110000 PPS empfangen können. Als Lösungsansatz habe ich dann \texttt{netcat} auf dem Port am Empfänger laufen lassen und die Daten nach \texttt{/dev/null} umgeleitet. Damit kamen keine Fehler mehr zustande und es konnten ca. 150000 PPS empfangen werden. Dies liegt jedoch immer noch weit unter den am Sender losgeschickten 450000 PPS und ist damit zu erklären, dass es für jedes Paket zu einem Kontex-Switch vom Kernel zu \texttt{netcat} kam und deshalb wieder die Bearbeitungszeit pro Paket stieg. \\ Letztendlich habe ich dazu entschieden, auf der Empfängerseite mit \texttt{iptables} die Pakete, die auf dem entsprechenden Port angekommen, direkt zu droppen. Damit konnten nun die zuvor erwähnten ca. 250000 PPS empfangen werden. \pagebreak \paragraph{Einfache Drop-Regeln} Für den nachfolgenden Benchmark habe ich entsprechend viele Regeln generieren lassen, die besagen, dass von (zufällig gewählten) IP-Adressen alle Pakete gedropt werden sollen. \\ \pgfplotstableread{benchmarks/nft/ipt-nft-simple-drop.txt}{\nftsimpledrop} \begin{minipage}{\textwidth} \flushright \begin{tikzpicture} \begin{axis}[ name=plot1, xtick={5000,10000,15000,20000,25000,30000}, xmin=200, xmax=30000, ymin=0, xlabel={Anzahl der Firewall-Regeln}, ylabel={Datenrate [MBit/s]}, tick label style={/pgf/number format/fixed,/pgf/number format/1000 sep = \thinspace}, width=15cm, height=10cm, legend entries={iptables,nftables}, scaled ticks=false ] \addplot[smooth,blue] table [x={rules}, y={iptrate}] {\nftsimpledrop}; \addplot[smooth,red] table [x={rules}, y={nftrate}] {\nftsimpledrop}; \end{axis} \begin{axis}[ name=plot2, at=(plot1.below south), anchor=above north, yshift=-0.5cm, xtick={5000,10000,15000,20000,25000,30000}, xmin=200, xmax=30000, ymin=0, xlabel={Anzahl der Firewall-Regeln}, ylabel={PPS}, tick label style={/pgf/number format/fixed,/pgf/number format/1000 sep = \thinspace}, width=15cm, height=10cm, legend entries={iptables,nftables}, scaled ticks=false ] \addplot[smooth,blue] table [x={rules}, y={iptpps}] {\nftsimpledrop}; \addplot[smooth,red] table [x={rules}, y={nftpps}] {\nftsimpledrop}; \end{axis} \end{tikzpicture} \end{minipage} \\ Die Datenrate und die Anzahl an PPS liegen initial bei den bereits zuvor gemessenen ca. 980 MBit/s und 250000 Paketen pro Sekunde. Jedoch bricht die Leistungsfähigkeit bei beiden Firewall-Lösungen schnell erheblich ein. So kann \texttt{iptables} bei 5000 Regeln nur noch ca. 100 MBit/s bei 28000 Paketen verarbeiten, \texttt{nftables} schafft hier nur ca. 50 MBit/s bei 14000 Paketen.