445 lines
24 KiB
TeX
445 lines
24 KiB
TeX
\chapter{\label{background}Background}
|
|
In this chapter we describe the key technologies involved.
|
|
\section{\label{background:P4}P4}
|
|
P4 is a programming language designed to program inside network
|
|
equipment. It's main features are protocol and target independence.
|
|
The \textit{protocol independence} refers to the separation of concerns in
|
|
terms of language and protocols: P4 generally speaking operates on
|
|
bits that are parsed and then accessible in the (self) defined
|
|
structures, also called headers. The general flow can be seen in
|
|
figure \ref{fig:p4fromnsg}: a parser parses the incoming packet and
|
|
prepares it for processing in the switching logic. Afterwards the
|
|
packets is output and deparsing of the parsed data might follow.
|
|
In the context of NAT64 this is a very important feature: while the
|
|
parser will read and parse in the ingress pipeline one protocol
|
|
(f.i. IPv6), the deparser will output a different protocol (f.i. IPv4).
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.9]{p4-from-nsg}
|
|
\centering
|
|
\caption{P4 protocol independence, \cite{vanbever:_progr_networ_data_planes}}
|
|
\label{fig:p4fromnsg}
|
|
\end{figure}
|
|
The \textit{target independence} is the second very powerful feature
|
|
of P4: it allows code to be compiled to different targets. While in
|
|
theory the P4 code should be completely target independent, in reality
|
|
there are some modifications needed on a per-target basis and each
|
|
target faces different restrictions. The challenges arising from this
|
|
are discussed in section \ref{conclusion:P4}.
|
|
|
|
As opposed to general purpose programming languages, P4 lacks some
|
|
features, most notably loops. However within its constraints, P4 can guarantee
|
|
operation at line speed, which general purpose programming languages
|
|
cannot guarantee and also fail to achieve in reality
|
|
(see section \ref{results:softwarenat64} for details).
|
|
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{background:ip}IPv6, IPv4 and Ethernet}
|
|
The first IPv6 RFC was published in 1998\cite{rfc2460}. Both IPv4 and
|
|
IPv4 operate on layer 3 of the OSI model. In this thesis we only
|
|
consider transmission via Ethernet, which operates at
|
|
layer 2. Inside the Ethernet frame a field named ``type'' specifies
|
|
the higher level protocol identifier (0x0800 for IPv4 \cite{rfc894}
|
|
and 0x86DD for IPv6 \cite{rfc2464}. This is important, because
|
|
Ethernet can only carry either of the two protocols.
|
|
The figures \ref{fig:ipv4header} and \ref{fig:ipv6header} show the
|
|
packet headers of IPv4 and IPv6. The most notable differences between
|
|
the two protocols for this thesis are:
|
|
\begin{itemize}
|
|
\item Different address lengths (32 vs 128 bit)
|
|
\item Lack of checksum in IPv6
|
|
\item Format of Pseudo headers (see section \ref{background:checksums})
|
|
\end{itemize}
|
|
\begin{figure}[h]
|
|
\begin{verbatim}
|
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|Version| Traffic Class | Flow Label |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Payload Length | Next Header | Hop Limit |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| |
|
|
+ +
|
|
| |
|
|
+ Source Address +
|
|
| |
|
|
+ +
|
|
| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| |
|
|
+ +
|
|
| |
|
|
+ Destination Address +
|
|
| |
|
|
+ +
|
|
| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
\end{verbatim}
|
|
\centering
|
|
\caption{IPv6 Header, \cite{rfc2460}}
|
|
\label{fig:ipv6header}
|
|
\end{figure}
|
|
|
|
\begin{figure}[h]
|
|
\begin{verbatim}
|
|
|
|
0 1 2 3
|
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|Version| IHL |Type of Service| Total Length |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Identification |Flags| Fragment Offset |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Time to Live | Protocol | Header Checksum |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Source Address |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Destination Address |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Options | Padding |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
\end{verbatim}
|
|
\caption{IPv4 Header, \cite{rfc791}}
|
|
\label{fig:ipv4header}
|
|
\end{figure}
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{background:arpndp}ARP and NDP, ICMP and ICMP6}
|
|
While IPv6 and IPv4 are primarily used as a ``shell'' to support
|
|
addressing for protocols that have no or limited addressing support
|
|
(like TCP or UDP), protocols like ARP \cite{rfc826} and NDP
|
|
\cite{rfc4861} provide support for resolving IPv6 and IPv4
|
|
addresses to hardware (MAC) addresses. While both ARP and NDP are only
|
|
used prior to establishing a connection on and their results are
|
|
cached, their availability is crucial for operating a switch.
|
|
Figure \ref{fig:arpndp} illustrates a typical address resolution process.
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.3]{arp-ndp}
|
|
\centering
|
|
\caption{ARP and NDP}
|
|
\label{fig:arpndp}
|
|
\end{figure}
|
|
The major difference between ARP and NDP in relation to P4 are
|
|
\begin{itemize}
|
|
\item ARP is a separate protocol on the same layer as IPv6 and IPv4,
|
|
\item NDP operates below ICMP6 which operates below IPv6,
|
|
\item NDP contains checksums over payload,
|
|
\item and NDP in ICMP6 contains optional, non referenced option fields
|
|
(specifically: ICMP6 link layer address option).
|
|
\end{itemize}
|
|
ARP is required to be a separate protocol, because IPv4 hosts don't
|
|
know how to communicate with each other yet, because they don't have a
|
|
way to communicate to the target IPv4 address (``The chicken and the
|
|
egg problem'').
|
|
NDP on the other hand already works within IPv6, as every IPv6 host is
|
|
required to have a self-assigned link local IPv6 address from the
|
|
range \texttt{fe80::/10} (compare RFC4291\cite{rfc4291}). NDP also
|
|
does not require broadcast communication, because hosts automatically
|
|
join multicast groups that embed parts of their
|
|
IPv6 addresses (\cite{rfc2710}, \cite{wikipedia:_solic}). This way the
|
|
collision domain is significantly reduced in IPv6, compared to IPv4.
|
|
|
|
As seen later in this document (compare
|
|
\ref{results:netpfga:checksum}), the requirement to generate checksums
|
|
over payload poses difficult problems for some hardware targets. Even
|
|
more difficult is the use of options within ICMP6. Figure shows a
|
|
typical layout of a neighbor advertisement messages.
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.3]{icmp6ndp}
|
|
\centering
|
|
\caption{ICMP6 option fields}
|
|
\label{fig:icmp6ndp}
|
|
\end{figure}
|
|
The problem arises from the layout of the options, as seen in the
|
|
following quote:
|
|
\begin{quote}
|
|
Neighbor Discovery messages include zero or more options, some of
|
|
which may appear multiple times in the same message. Options should
|
|
be padded when necessary to ensure that they end on their natural
|
|
64-bit boundaries.\footnote{From RFC4861.}
|
|
\end{quote}
|
|
|
|
ICMP6 and ICMP are primarily used to signal errors in
|
|
communication. Specifically signalling that a packet is too big to
|
|
pass a certain link and needs fragmentation is a common functionality
|
|
of both protocols. For a host (or switch) to be able to emit ICMP6 and
|
|
ICMP messages, the host requires a valid IPv6 / IPv4 address.
|
|
Without ICMP6 / ICMP support path mtu discovery (\cite{rfc1191},
|
|
\cite{rfc8201}) does not work and the sender needs to determine
|
|
different ways of finding out the maximum MTU on the path.
|
|
% ok -- need to separate backgroun and results
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{background:transition}IPv6 Translation Mechanisms}
|
|
While in this thesis the focus was in NAT64 as a translation mechanism,
|
|
there are a variety of different approaches, some of which we would
|
|
like to portray here.
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:transition:staticnat64}Static NAT64}
|
|
Static NAT64 describes static mappings between IPv6 and IPv4
|
|
addresses. This can be based on longest prefix matchings (LPM),
|
|
ranges, bitmasks or individual entries.
|
|
|
|
NAT64 translations as described in this thesis modify multiple layers
|
|
in the translation process:
|
|
|
|
\begin{itemize}
|
|
\item Ethernet (changing the type field)
|
|
\item IPv4 / IPv6 (changing the protocol, changing the fields)
|
|
\item TCP/UDP/ICMP/ICMP6 checksums
|
|
\end{itemize}
|
|
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:transition:statefulnat64}Stateful NAT64}
|
|
Stateful NAT64 as defined in RFC6146\cite{rfc6146} defines how to
|
|
cretate 1:n mappings between IPv6 and IPv4 hosts. The motivation for
|
|
stateful NAT64 is similar to stateful NAT44\cite{/rfc3022}: it allows
|
|
translating many IPv6 addresses to one IPv4 address. While the
|
|
opposite translation is also technically possible, the differences in
|
|
address space don't justify its use in general.
|
|
|
|
Stateful NAT64 in particular uses information in higher level
|
|
protocols to multiplex connections: Given one IPv4 address and the tcp
|
|
protocol, outgoing connections from IPv6 hosts can dynamically mapped
|
|
to the range of possible tcp ports. After a session is closed, the
|
|
port can be reused again.
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.5]{statefulnat64}
|
|
\centering
|
|
\caption{Stateful NAT64}
|
|
\label{fig:statefulnat64}
|
|
\end{figure}
|
|
The selection of mapped ports is usually based on the availability on
|
|
the IPv4 side and not related to the original port. To support
|
|
stateful NAT64, the translator needs to store the mapping in a table and
|
|
purge entries regularly.
|
|
|
|
Stateful usually NAT64 uses information found in protocols at layer 4
|
|
like TCP \cite{rfc793} or UDP \cite{rfc768}. However it can also
|
|
support ICMP \cite{rfc792} or ICMP6 \cite{rfc4443}.
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:transition:Protocol dependent}Higher
|
|
layer Protocol Dependent Translation}
|
|
Further translation can be achieved by using information in higher
|
|
level protocols like HTTP \cite{rfc2616} or TLS
|
|
\cite{rfc4366}. Application proxies like nginx
|
|
\cite{nginx:_nginx_high_perfor_load_balan} use layer 7 protocol
|
|
information to proxy towards backends. Within this proxying method,
|
|
the underlying IP protocol can be changed from IPv6 to IPv4 and vice
|
|
versa. However the requested hostname that is usually used for
|
|
selecting the backend is encrypted in TLS 1.3 \cite{rfc8446}, which
|
|
poses a challenge for implementations.
|
|
|
|
While protocol dependent translation has the highest amount of
|
|
information to choose from for translation, complex parsers or even
|
|
cryptographic methods are required for it. That reduces the
|
|
opportunities of protocol dependent translation
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:transition:dns64}DNS64 - FIXME}
|
|
|
|
DNS64 \cite{rfc6174}
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:transition:prefixnat}Prefix based NAT -
|
|
FIXME}
|
|
Explain how it works in general
|
|
**** RFC6052
|
|
- Defining well known prefix 64:ff9b::/96
|
|
- Defining embedding depending on prefix: /32../104 in 8 bit
|
|
steps
|
|
- Longer than /96: suffix support
|
|
|
|
|
|
- v4 to v6 / vice versa
|
|
|
|
\begin{verbatim}
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|PL| 0-------------32--40--48--56--64--72--80--88--96--104---------|
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|32| prefix |v4(32) | u | suffix |
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|40| prefix |v4(24) | u |(8)| suffix |
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|48| prefix |v4(16) | u | (16) | suffix |
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|56| prefix |(8)| u | v4(24) | suffix |
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|64| prefix | u | v4(32) | suffix |
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|96| prefix | v4(32) |
|
|
+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
|
|
|
|
|
***** DONE Case IPv6 initiator
|
|
CLOSED: [2019-08-13 Tue 10:59]
|
|
- Mapping whole IPv4 Internet in /96 prefix
|
|
- Session information for mapping reply
|
|
- Timeout handling in controller
|
|
****** TODO IPv6 udp -> IPv4
|
|
- Got 4-5 tuple ([proto], src ip, src port, dst ip, dst port)
|
|
- Does not / never signal end
|
|
- Needs timeout for cleaning up
|
|
****** TODO IPv6 tcp -> IPv4
|
|
- Similar to udp
|
|
- react on FIN/RST (?) -- could be an addition
|
|
****** TODO IPv6 icmp6 -> IPv4
|
|
- usual protocol specific changes
|
|
- Session??
|
|
- src ip, dst ip, code ?
|
|
***** TODO Case IPv4 initiator
|
|
- Needs upper level protol
|
|
|
|
|
|
****** Controller Logic
|
|
- controller selects "outgoing" IPv4 address range => base for sessions
|
|
- IPv4 addresses can be "random" (in our test case), but need
|
|
to be unique
|
|
- switch does not need to know about the "range", only about
|
|
sessions
|
|
- on session create, controller selects "random" ip (ring?)
|
|
- on session create, controller selects "random port" (next in range?)
|
|
- on session create controller adds choice into 2 tables:
|
|
incoming, outgoing
|
|
|
|
|
|
>>> ipaddress.IPv6Network("2001:db8:100::/96")[int(ipaddress.IPv4Address("10.0.0.1"))]
|
|
IPv6Address('2001:db8:100::a00:1')
|
|
\end{verbatim}
|
|
from RFC6052
|
|
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{background:checksums}Protocol Checksums}
|
|
One challenge for translating IPv6-IPv4 are checksums of higher level
|
|
protocols like TCP and UDP that incorporate information from the lower
|
|
level protocols. The pseudo header for upper layer protocols for
|
|
IPv6 is defined in RFC2460 \cite{rfc2460} and shown in figure
|
|
\ref{fig:ipv6pseudoheader}, the IPv4 pseudo header for TCP and UDP are
|
|
defined in RFC768 and RFC793 and are shown in \ref{fig:ipv4pseudoheader}.
|
|
\begin{figure}[h]
|
|
\begin{verbatim}
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| |
|
|
+ +
|
|
| |
|
|
+ Source Address +
|
|
| |
|
|
+ +
|
|
| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| |
|
|
+ +
|
|
| |
|
|
+ Destination Address +
|
|
| |
|
|
+ +
|
|
| |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| Upper-Layer Packet Length |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
| zero | Next Header |
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
\end{verbatim}
|
|
\centering
|
|
\caption{IPv6 Pseudo Header}
|
|
\label{fig:ipv6pseudoheader}
|
|
\end{figure}
|
|
When translating, the checksum fields in the higher protocols need to be
|
|
adjusted. The checksums for TCP and UDP is calculated not only over the pseudo
|
|
headers, but also contain the payload of the packet. This is
|
|
important, because some targets (like the NetPFGA) do not allow to
|
|
access the payload.
|
|
\begin{figure}[h]
|
|
\begin{verbatim}
|
|
0 7 8 15 16 23 24 31
|
|
+--------+--------+--------+--------+
|
|
| source address |
|
|
+--------+--------+--------+--------+
|
|
| destination address |
|
|
+--------+--------+--------+--------+
|
|
| zero |protocol| UDP length |
|
|
+--------+--------+--------+--------+
|
|
|
|
\end{verbatim}
|
|
\centering
|
|
\caption{IPv4 Pseudo Header}
|
|
\label{fig:ipv4pseudoheader}
|
|
\end{figure}
|
|
% ----------------------------------------------------------------------
|
|
\section{\label{background:networkdesign}Network Designs}
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.5]{v4only}
|
|
\centering
|
|
\caption{IPv4 only network}
|
|
\label{fig:v4onlynet}
|
|
\end{figure}
|
|
In relation to IPv6 and IPv4, there are in general three different
|
|
network designs possible:
|
|
The oldest form are IPv4 only networks (see figure
|
|
\ref{fig:v4onlynet}.
|
|
These networks consist of
|
|
hosts that are either not configured for IPv6 or are even technically
|
|
incapable of enabling the IPv6 protocol. These nodes are connected to
|
|
an IPv4 router that is connected to the Internet. That router might be
|
|
capable of translating IPv4 to IPv6 and vice versa.
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.5]{dualstack}
|
|
\centering
|
|
\caption{Dualstack network}
|
|
\label{fig:dualstacknet}
|
|
\end{figure}
|
|
With the introduction of IPv6, hosts can have a separate IP stack
|
|
active and in that configuration hosts are called ``dualstack hosts''
|
|
(see figure \ref{fig:dualstacknet}).
|
|
Dualstack hosts are capabale of reaching both IPv6 and IPv4 hosts
|
|
directly without the need of any translation mechanism.
|
|
|
|
The last possible network design is based on IPv6 only hosts, as shown
|
|
in figure \ref{fig:v6onlynet}. While it is technically easy to disable IPv4, it
|
|
seems that completely removing the IPv4 stack in current operating
|
|
systems is not an easy task \cite{ungleich:_ipv4}.
|
|
\begin{figure}[h]
|
|
\includegraphics[scale=0.5]{v6only}
|
|
\centering
|
|
\caption{IPv6 only network}
|
|
\label{fig:v6onlynet}
|
|
\end{figure}
|
|
While the three network designs look similar, there are significant
|
|
differences in operating them and limitations that are not easy to
|
|
circumvent. In the following sections we describe the limitations and
|
|
reason how a translation mechanism like our NAT64 implementation
|
|
should be deployed.
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:networkdesign:ipv4}IPv4 only network limitations}
|
|
As shown in figures \ref{fig:ipv4header} and \ref{fig:ipv6header}
|
|
the IPv4 address size is 32 bit, while the IPv6 address size is 128
|
|
bit.
|
|
Without an extension to the address space, there is no protocol independent
|
|
mapping of IPv4 address to IPv6 (see section
|
|
\ref{background:transition:nat64})
|
|
that can cover the whole IPv6 address space. Thus IPv4 only hosts can
|
|
never address every host in the IPv6 Internet. While protocol
|
|
dependent translations can try to minimise the impact, accessing all
|
|
IPv6 addresses independent of the protcol is not possible.
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:networkdesign:dualstack}Dualstack network
|
|
maintenance}
|
|
While dualstack hosts can address any host in either IPv6 or IPv4
|
|
networks, the deployment of dualstack hosts comes with a major
|
|
disadvantage: all network configuration double. The required routing
|
|
tables double, the firewall rules roughly double\footnote{The rulesets
|
|
even for identical policies in IPv6 and IPv4 networks are not
|
|
identical, but similar. For this reason we state that roughly double
|
|
the amount of firewall rules are required for the same policy to be
|
|
applied.} and the number of network supporting systems (like DHCPv4,
|
|
DHCPv6, router advertisement daemons, etc.) also roughly double.
|
|
Additionally services that run on either IPv6 or IPv4 might need to be
|
|
configured to run in dualstack mode as well and not every software
|
|
might be capable of that.
|
|
So while there is the instant benefit of not requiring any transition mechanism
|
|
or translation method, we argue that the added complexity (and thus
|
|
operational cost) of running dual stack networks can be significant.
|
|
% ----------------------------------------------------------------------
|
|
\subsection{\label{background:networkdesign:v6only}IPv6 only networks}
|
|
IPv6 only networks are in our opinion the best choice for long term
|
|
deployments. The reasons for this are as follows: First of all hosts
|
|
eventually will need to support IPv6 and secondly
|
|
IPv6 hosts can address the whole 32 bit IPv4 Internet mapped in
|
|
a single /96 IPv6 network. IPv6 only networks also allow the operators
|
|
to focus on one IP stack.
|