\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.