149 lines
5.9 KiB
TeX
149 lines
5.9 KiB
TeX
\chapter{\label{design}Design}
|
|
Description of the theory/software/hardware that you designed.
|
|
%** Design.tex: How was the problem attacked, what was the design
|
|
% the architecture
|
|
In this chapter we describe the architecture of our solution.
|
|
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{Design:General}General}
|
|
The high level design can be seen in figure \ref{fig:switchdesign}: a
|
|
P4 capable switch is running our code to provide NAT64
|
|
functionality. The P4 switch cannot manage its tables on it own and
|
|
needs support for this from a controller. If only static table entries
|
|
are required, the controller can also be omitted. However stateful
|
|
NAT64 requires the use of a control to create session entries in the
|
|
switch tables.
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.5]{switchdesign}
|
|
\centering
|
|
\caption{General Design}
|
|
\label{fig:switchdesign}
|
|
\end{figure}
|
|
The P4 switch can use any protocol to communicate with controller, as
|
|
the connection to the controller is implemented as a separate ethernet
|
|
port. The design allows our solution to be used as a standard NAT64
|
|
translation method or as an in network NAT64 translation (compare
|
|
figures \ref{fig:v6v4innetwork} and \ref{fig:v6v4standard}). The
|
|
controller is implemented in python, the NAT64 solution is implemented
|
|
in P4.
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{Design:BMV2}BMV2}
|
|
Development of the thesis took place on a software emulated switch
|
|
that is implemented using Open vSwitch \cite{openvswitch}
|
|
and the behavioral model
|
|
\cite{_implem_your_switc_target_with_bmv2}. The development followed
|
|
closely the general design shown in section
|
|
\ref{Design:General}. Within the software emulation checksums can be
|
|
computed with two different methods:
|
|
\begin{itemize}
|
|
\item Recalculating the checksum by inspecting headers and payload
|
|
\item Calculating the difference between the translated headers
|
|
\end{itemize}
|
|
The BMV2 model is rather sophisticated and provides many standard
|
|
features including checksumming over payload. This allows the BMV2
|
|
model to operate as a full featured host, including advanced features
|
|
like responding to ICMP6 Neighbor discovery requests \cite{rfc4861}
|
|
that include payload checksums.
|
|
A typical code to create the checksum can be found in figure
|
|
\ref{fig:checksum}.
|
|
\begin{figure}[h]
|
|
\begin{verbatim}
|
|
/* checksumming for icmp6_na_ns_option */
|
|
update_checksum_with_payload(meta.chk_icmp6_na_ns == 1,
|
|
{
|
|
hdr.ipv6.src_addr, /* 128 */
|
|
hdr.ipv6.dst_addr, /* 128 */
|
|
meta.cast_length, /* 32 */
|
|
24w0, /* 24 0's */
|
|
PROTO_ICMP6, /* 8 */
|
|
hdr.icmp6.type, /* 8 */
|
|
hdr.icmp6.code, /* 8 */
|
|
|
|
hdr.icmp6_na_ns.router,
|
|
hdr.icmp6_na_ns.solicitated,
|
|
hdr.icmp6_na_ns.override,
|
|
hdr.icmp6_na_ns.reserved,
|
|
hdr.icmp6_na_ns.target_addr,
|
|
|
|
hdr.icmp6_option_link_layer_addr.type,
|
|
hdr.icmp6_option_link_layer_addr.ll_length,
|
|
hdr.icmp6_option_link_layer_addr.mac_addr
|
|
},
|
|
hdr.icmp6.checksum,
|
|
HashAlgorithm.csum16
|
|
);
|
|
\end{verbatim}
|
|
\centering
|
|
\caption{IPv4 Pseudo Header}
|
|
\label{fig:checksum}
|
|
\end{figure}
|
|
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{Design:NetPFGA}NetFPGA}
|
|
While the P4-NetFPGA project \cite{netfpga:_p4_netpf_public_github}
|
|
allows compiling P4 to the NetPFGA, the design slightly varies.
|
|
In particular, the NetFPGA P4 compiler does not support reading
|
|
the payload. For this reason it also does not support
|
|
creating the checksum based on the payload.
|
|
To support checksum modifications in NAT64 on the NetFPGA, the
|
|
checksum was calculated on the netpfga using differences between
|
|
the IPv6 and IPv4 headers. Figure \ref{fig:checksumbydiff} shows an
|
|
excerpt of the code used for calculating checksums in the netpfga.
|
|
\begin{figure}[h]
|
|
\begin{verbatim}
|
|
action v4sum() {
|
|
bit<16> tmp = 0;
|
|
|
|
tmp = tmp + (bit<16>) hdr.ipv4.src_addr[15:0]; // 16 bit
|
|
tmp = tmp + (bit<16>) hdr.ipv4.src_addr[31:16]; // 16 bit
|
|
tmp = tmp + (bit<16>) hdr.ipv4.dst_addr[15:0]; // 16 bit
|
|
tmp = tmp + (bit<16>) hdr.ipv4.dst_addr[31:16]; // 16 bit
|
|
|
|
tmp = tmp + (bit<16>) hdr.ipv4.totalLen -20; // 16 bit
|
|
tmp = tmp + (bit<16>) hdr.ipv4.protocol; // 8 bit
|
|
|
|
meta.v4sum = ~tmp;
|
|
}
|
|
|
|
/* analogue code for v6sum skipped */
|
|
|
|
action delta_tcp_from_v6_to_v4()
|
|
{
|
|
v6sum();
|
|
v4sum();
|
|
|
|
bit<17> tmp = (bit<17>) hdr.tcp.checksum + (bit<17>) meta.v4sum;
|
|
if (tmp[16:16] == 1) {
|
|
tmp = tmp + 1;
|
|
tmp[16:16] = 0;
|
|
}
|
|
tmp = tmp + (bit<17>) (0xffff - meta.v6sum);
|
|
if (tmp[16:16] == 1) {
|
|
tmp = tmp + 1;
|
|
tmp[16:16] = 0;
|
|
}
|
|
|
|
hdr.tcp.checksum = (bit<16>) tmp;
|
|
}
|
|
|
|
\end{verbatim}
|
|
\centering
|
|
\caption{Calculating checksum based on header differences}
|
|
\label{fig:checksumbydiff}
|
|
\end{figure}
|
|
The checksums for IPv4, TCP, UDP and ICMP6 are all based on the
|
|
``Internet Checksum'' (\cite{rfc791}, \cite{rfc1071}). Its calculation
|
|
can be summarised as follows:
|
|
\begin{quote}
|
|
The checksum field is the 16-bit one's complement of the one's
|
|
complement sum of all 16-bit words in the header. For purposes of
|
|
computing the checksum, the value of the checksum field
|
|
is zero.\footnote{Quote from Wikipedia\cite{wikipedia:_ipv4}.}.
|
|
\end{quote}
|
|
As the calculation mainly depends on on (1-complement) sums, the
|
|
checksums after translating the protocol can be corrected by
|
|
subtracting the differences of the relevant fields. It is notable that
|
|
not the full headers are used, but the pseudo headers (compare figures
|
|
\ref{fig:ipv6pseudoheader} and \ref{fig:ipv4pseudoheader}).
|
|
To compensate the carry bit, our code uses 17 bit integers for
|
|
correcting the carry.
|