OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

virtio-dev message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: Re: [virtio-dev] [PATCH] virtio-net: define UDP tunnel offload feature


On Wed, May 18, 2022 at 6:16 PM Paolo Abeni <pabeni@redhat.com> wrote:
>
> The VIRTIO_NET_HDR_GSO_UDP_TUNNEL is a gso_type flags allowing
> GSO over UDP tunnel. It can be negotiated on both the host and
> guest side.
>
> UDP tunnel usage is ubiquitous in container deployment, and the
> ability to offload UDP encapsulated GSO traffic impacts greatly
> the performances and the CPU utilization of such use-case
>
> To keep the design relatively simple, this copes only with tunneling
> scenarios including an inner ethernet MAC header - e.g. inner network
> on top of the UDP encapsulation is not allowed.
>
> Other than that the new flag is designed to be independent from the
> specific UDP tunnel encapsulation - geneve, vxlan, etc.
>
> The outer UDP header may carry a second checksum, which can be
> offloaded independently from the inner one. We don't need to specify
> the location of such checksum, as both the host and the guest can infer
> its location the same way they currently do for the transport header for
> plain GSO packets.

I'm not sure I get this, the transport header is set based on
csum_start currently. More below.

>
> One constraint addressed here is that the virtio side (either device or
> driver) receiving an UDP tunneled GSO packet must be able to reconstruct
> completely the inner and outer headers offset - to allow for later GSO.
>
> To accommodate such need the hdr_len field is [re-]used: when
> the UDP tunnel feature is negotiated and the VIRTIO_NET_HDR_GSO_UDP_TUNNEL
> is set, such field is used to identify the inner network header.
>
> All the other inner/outer headers location can be computed from the
> above info.
>
> Note that when the VIRTIO_NET_HDR_GSO_UDP_TUNNEL flag is not set,
> the current semantic for the hdr_hen field does not change.
>
> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> ---
>  content.tex | 110 +++++++++++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 96 insertions(+), 14 deletions(-)
>
> diff --git a/content.tex b/content.tex
> index c6f116c..8825d81 100644
> --- a/content.tex
> +++ b/content.tex
> @@ -3092,6 +3092,16 @@ \subsection{Feature bits}\label{sec:Device Types / Network Device / Feature bits
>  \item[VIRTIO_NET_F_CTRL_MAC_ADDR(23)] Set MAC address through control
>      channel.
>
> +\item[VIRTIO_NET_F_GUEST_UDP_TUNNEL (54)] Driver can receive GSO packets
> +  carried by an UDP tunnel. The tunnel encapsulation is constrained to have
> +  constant size and carring an inner ethernet header. e.g. alike vxlan and

I think you mean "carrying" here.

> +  geneve defaults.
> +
> +\item[VIRTIO_NET_F_HOST_UDP_TUNNEL (55)] Device can receive GSO packets
> +  carried by an UDP tunnel. The tunnel encapsulation is constrained to have
> +  constant size and carring an inner ethernet header. e.g. alike vxlan and

And here.

> +  geneve defaults.
> +
>  \item[VIRTIO_NET_F_HOST_USO (56)] Device can receive USO packets. Unlike UFO
>   (fragmenting the packet) the USO splits large UDP packet
>   to several segments when each of these smaller packets has UDP header.
> @@ -3125,12 +3135,14 @@ \subsubsection{Feature bit requirements}\label{sec:Device Types / Network Device
>  \item[VIRTIO_NET_F_GUEST_TSO6] Requires VIRTIO_NET_F_GUEST_CSUM.
>  \item[VIRTIO_NET_F_GUEST_ECN] Requires VIRTIO_NET_F_GUEST_TSO4 or VIRTIO_NET_F_GUEST_TSO6.
>  \item[VIRTIO_NET_F_GUEST_UFO] Requires VIRTIO_NET_F_GUEST_CSUM.
> +\item[VIRTIO_NET_F_GUEST_UDP_TUNNEL] Requires VIRTIO_NET_F_GUEST_TSO4 or VIRTIO_NET_F_GUEST_TSO6
>
>  \item[VIRTIO_NET_F_HOST_TSO4] Requires VIRTIO_NET_F_CSUM.
>  \item[VIRTIO_NET_F_HOST_TSO6] Requires VIRTIO_NET_F_CSUM.
>  \item[VIRTIO_NET_F_HOST_ECN] Requires VIRTIO_NET_F_HOST_TSO4 or VIRTIO_NET_F_HOST_TSO6.
>  \item[VIRTIO_NET_F_HOST_UFO] Requires VIRTIO_NET_F_CSUM.
>  \item[VIRTIO_NET_F_HOST_USO] Requires VIRTIO_NET_F_CSUM.
> +\item[VIRTIO_NET_F_HOST_UDP_TUNNEL] Requires VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6 or VIRTIO_NET_F_HOST_USO
>
>  \item[VIRTIO_NET_F_CTRL_RX] Requires VIRTIO_NET_F_CTRL_VQ.
>  \item[VIRTIO_NET_F_CTRL_VLAN] Requires VIRTIO_NET_F_CTRL_VQ.
> @@ -3337,6 +3349,9 @@ \subsection{Device Initialization}\label{sec:Device Types / Network Device / Dev
>    segmentation/fragmentation offload by negotiating the VIRTIO_NET_F_HOST_TSO4 (IPv4
>    TCP), VIRTIO_NET_F_HOST_TSO6 (IPv6 TCP), VIRTIO_NET_F_HOST_UFO
>    (UDP fragmentation) and VIRTIO_NET_F_HOST_USO (UDP segmentation) features.
> +  Additionally, it can negotiate the VIRTIO_NET_F_HOST_UDP_TUNNEL feature to
> +  use TCP segmentation or UDP segmentation on top of UDP encapsulation,
> +  respecting the other negotiated features.
>
>  \item The converse features are also available: a driver can save
>    the virtual device some work by negotiating these features.\note{For example, a network packet transported between two guests on
> @@ -3345,8 +3360,8 @@ \subsection{Device Initialization}\label{sec:Device Types / Network Device / Dev
>     The VIRTIO_NET_F_GUEST_CSUM feature indicates that partially
>    checksummed packets can be received, and if it can do that then
>    the VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
> -  VIRTIO_NET_F_GUEST_UFO and VIRTIO_NET_F_GUEST_ECN are the input
> -  equivalents of the features described above.
> +  VIRTIO_NET_F_GUEST_UFO, VIRTIO_NET_F_GUEST_ECN and VIRTIO_NET_F_GUEST_UDP_TUNNEL
> +  are the input equivalents of the features described above.
>    See \ref{sec:Device Types / Network Device / Device Operation /
>  Setting Up Receive Buffers}~\nameref{sec:Device Types / Network
>  Device / Device Operation / Setting Up Receive Buffers} and
> @@ -3370,12 +3385,14 @@ \subsection{Device Operation}\label{sec:Device Types / Network Device / Device O
>  #define VIRTIO_NET_HDR_F_NEEDS_CSUM    1
>  #define VIRTIO_NET_HDR_F_DATA_VALID    2
>  #define VIRTIO_NET_HDR_F_RSC_INFO      4
> +#define VIRTIO_NET_HDR_F_UDP_TUNNEL_CSUM 8
>          u8 flags;
>  #define VIRTIO_NET_HDR_GSO_NONE        0
>  #define VIRTIO_NET_HDR_GSO_TCPV4       1
>  #define VIRTIO_NET_HDR_GSO_UDP         3
>  #define VIRTIO_NET_HDR_GSO_TCPV6       4
>  #define VIRTIO_NET_HDR_GSO_UDP_L4      5
> +#define VIRTIO_NET_HDR_GSO_UDP_TUNNEL 0x40
>  #define VIRTIO_NET_HDR_GSO_ECN      0x80
>          u8 gso_type;
>          le16 hdr_len;
> @@ -3443,6 +3460,8 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>  followed by the TCP header (with the TCP checksum field 16 bytes
>  into that header). \field{csum_start} will be 14+20 = 34 (the TCP
>  checksum includes the header), and \field{csum_offset} will be 16.
> +If the given packets has the VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit set,
> +the above checksum fields refer to the inner header checksum.
>  \end{note}

I think we need to explain how the outer checksum is expected to work.
It looks to me it requires the device to examine/probe the outer
packet header. If it's true, I wonder what happen if the device fail
to do such probing.

>
>  \item If the driver negotiated
> @@ -3455,11 +3474,16 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>    into smaller packets. The other gso fields are set:
>
>    \begin{itemize}
> -  \item If the VIRTIO_NET_F_GUEST_HDRLEN feature has been negotiated,
> +  \item If the VIRTIO_NET_F_HOST_UDP_TUNNEL feature has been negotiated and
> +    the VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is set,
> +    \field{hdr_len} indicates the location of the inner network header.

It's probably better to explain why a network header instead of
transport header is needed here. (Anyhow we're doing segmentation at
L4 instead of L3).

> +    Otherwise, if the VIRTIO_NET_F_GUEST_HDRLEN feature has been negotiated
> +    and the VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is not set,

I wonder if this just suppress the semantic of GUEST_HDR_LEN. If yes,
is this better to have dedicated inner hdr len?

>      \field{hdr_len} indicates the header length that needs to be replicated
>      for each packet. It's the number of bytes from the beginning of the packet
>      to the beginning of the transport payload.
> -    Otherwise, if the VIRTIO_NET_F_GUEST_HDRLEN feature has not been negotiated,
> +    Finally, if the VIRTIO_NET_F_GUEST_HDRLEN and VIRTIO_NET_F_HOST_UDP_TUNNEL
> +    the features has not been negotiated,
>      \field{hdr_len} is a hint to the device as to how much of the header
>      needs to be kept to copy into each packet, usually set to the
>      length of the headers, including the transport header\footnote{Due to various bugs in implementations, this field is not useful
> @@ -3477,6 +3501,13 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>      the VIRTIO_NET_HDR_GSO_ECN bit in \field{gso_type}
>      indicates that the TCP packet has the ECN bit set\footnote{This case is not handled by some older hardware, so is called out
>  specifically in the protocol.}.
> +
> +  \item If the driver negotiated the VIRTIO_NET_F_HOST_UDP_TUNNEL feature,
> +    \field{gso_type} has the VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit set,
> +    \field{flags} has the VIRTIO_NET_HDR_F_UDP_TUNNEL_CSUM set, the outer
> +    UDP checksum field carries the checksum for the UDP pseudo header,
> +    the complete UDP checksum can be computed in a similar way to the
> +    inner TCP.

This looks like a partial offload of the outer checksum, if yes, we
probably need a better name of the flag (maybe
UDP_TUNNEL_PARTIAL_CSUM)? This is because VIRTIO_NET_HDR_F_CSUM is
used for complete offloading.

>     \end{itemize}
>
>  \item \field{num_buffers} is set to zero.  This field is unused on transmitted packets.
> @@ -3520,6 +3551,11 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>  driver MUST set the VIRTIO_NET_HDR_GSO_ECN bit in
>  \field{gso_type}.
>
> +The driver MUST NOT sent to the device TCP or UDP packets over UDP tunnel
> +requiring segmentation offload, unless the VIRTIO_NET_F_HOST_UDP_TUNNEL is
> +negotiated, in which case the driver MUST set the VIRTIO_NET_HDR_GSO_UDP_TUNNEL
> +bit in the \field{gso_type}.

Do we need to clarify that inner UFO is forbidden even with UDP_TUNNEL?

> +
>  If the VIRTIO_NET_F_CSUM feature has been negotiated, the
>  driver MAY set the VIRTIO_NET_HDR_F_NEEDS_CSUM bit in
>  \field{flags}, if so:
> @@ -3549,7 +3585,13 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>  If one of the VIRTIO_NET_F_HOST_TSO4, TSO6, USO or UFO options have
>  been negotiated:
>  \begin{itemize}
> -\item If the VIRTIO_NET_F_GUEST_HDRLEN feature has been negotiated,
> +\item If the VIRTIO_NET_F_HOST_UDP_TUNNEL feature has been negotiated,
> +       and the \field{gso_type} VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is
> +       set, the driver MUST set \field{hdr_len} to a value equal to
> +       the inner network header offset.
> +
> +\item If the \field{gso_type} VIRTIO_NET_HDR_GSO_UDP_TUNNEL is not set,
> +       the VIRTIO_NET_F_GUEST_HDRLEN feature has been negotiated,
>         and \field{gso_type} differs from VIRTIO_NET_HDR_GSO_NONE,
>         the driver MUST set \field{hdr_len} to a value equal to the length
>         of the headers, including the transport header.
> @@ -3576,7 +3618,18 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>  If one of the VIRTIO_NET_F_HOST_TSO4, TSO6, USO or UFO options have
>  been negotiated:
>  \begin{itemize}
> -\item If the VIRTIO_NET_F_GUEST_HDRLEN feature has been negotiated,
> +\item If the VIRTIO_NET_F_HOST_UDP_TUNNEL feature has been negotiated,
> +       and the \field{gso_type} VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is
> +       set, the driver MUST use \field{hdr_len} as the inner network
> +       header offset.
> +
> +       \begin{note}
> +       Caution should be taken by the implementation so as to prevent
> +       a malicious driver from attacking the device by setting an incorrect hdr_len.
> +       \end{note}
> +
> +\item If the \field{gso_type} VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is not set,
> +       the VIRTIO_NET_F_GUEST_HDRLEN feature has been negotiated,
>         and \field{gso_type} differs from VIRTIO_NET_HDR_GSO_NONE,
>         the device MAY use \field{hdr_len} as the transport header size.
>
> @@ -3585,7 +3638,8 @@ \subsubsection{Packet Transmission}\label{sec:Device Types / Network Device / De
>         a malicious driver from attacking the device by setting an incorrect hdr_len.
>         \end{note}
>
> -\item If the VIRTIO_NET_F_GUEST_HDRLEN feature has not been negotiated,
> +\item If the VIRTIO_NET_F_HOST_UDP_TUNNEL feature has not been negotiated,
> +       the VIRTIO_NET_F_GUEST_HDRLEN feature has not been negotiated,
>         or \field{gso_type} is VIRTIO_NET_HDR_GSO_NONE,
>         the device MAY use \field{hdr_len} only as a hint about the
>         transport header size.
> @@ -3689,8 +3743,8 @@ \subsubsection{Processing of Incoming Packets}\label{sec:Device Types / Network
>    has been validated.
>  \end{enumerate}
>
> -Additionally, VIRTIO_NET_F_GUEST_CSUM, TSO4, TSO6, UDP and ECN
> -features enable receive checksum, large receive offload and ECN
> +Additionally, VIRTIO_NET_F_GUEST_CSUM, TSO4, TSO6, UDP, UDP_TUNNEL
> +and ECN features enable receive checksum, large receive offload and ECN
>  support which are the input equivalents of the transmit checksum,
>  transmit segmentation offloading and ECN features, as described
>  in \ref{sec:Device Types / Network Device / Device Operation /
> @@ -3700,6 +3754,14 @@ \subsubsection{Processing of Incoming Packets}\label{sec:Device Types / Network
>    negotiated, then \field{gso_type} MAY be something other than
>    VIRTIO_NET_HDR_GSO_NONE, and \field{gso_size} field indicates the
>    desired MSS (see Packet Transmission point 2).
> +\item If the VIRTIO_NET_F_GUEST_UDP_TUNNEL option was negotiated and
> +  \field{gso_type} is not VIRTIO_NET_HDR_GSO_NONE, the VIRTIO_NET_HDR_GSO_UDP_TUNNEL
> +  bit MAY be set, and the \field{hdr_len} field indicates the
> +  inner network header offset (see Packet Transmission point 2).
> +  Additionally, the VIRTIO_NET_HDR_F_UDP_TUNNEL_CSUM bit in the
> +  \field{flags} MAY be set, indicating that the outer UDP header
> +  carries the UDP pseudo header csum and that the full UDP checksum
> +  (see Packet Transmission point 2).
>  \item If the VIRTIO_NET_F_RSC_EXT option was negotiated (this
>    implies one of VIRTIO_NET_F_GUEST_TSO4, TSO6), the
>    device processes also duplicated ACK segments, reports
> @@ -3759,6 +3821,19 @@ \subsubsection{Processing of Incoming Packets}\label{sec:Device Types / Network
>  which have the Explicit Congestion Notification bit set, unless the
>  VIRTIO_NET_F_GUEST_ECN feature is negotiated, in which case the
>  device MUST set the VIRTIO_NET_HDR_GSO_ECN bit in
> +
> +The device SHOULD NOT send to the driver TCP or UDP packets encapsulated in UDP
> +tunnel and requiring segmentation offload, unless the
> +VIRTIO_NET_F_GUEST_UDP_TUNNEL is negotiated, in which case the device MUST set
> +the VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit in \field{gso_type}. If the outer UDP
> +header carries a non 0 checksum:
> +\begin{enumerate}
> +\item the device MUST set the VIRTIO_NET_HDR_F_UDP_TUNNEL_CSUM bit in
> +       \field{flags}
> +\item the device MUST set the outer UDP header checksum field to the outer
> +       UDP pseudo header
> +\end{enumerate}
> +
>  \field{gso_type}.
>
>  If the VIRTIO_NET_F_GUEST_CSUM feature has been negotiated, the
> @@ -3778,6 +3853,12 @@ \subsubsection{Processing of Incoming Packets}\label{sec:Device Types / Network
>         fully checksummed packet;
>  \end{enumerate}
>
> +\begin{note}
> +If the VIRTIO_NET_F_GUEST_UDP_TUNNEL feature is negotiated and the
> +VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is set, the VIRTIO_NET_HDR_F_NEEDS_CSUM
> +bit refears to the inner header checksum

"refers"?

Thanks

> +\end{note}
> +
>  If none of the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options have
>  been negotiated, the device MUST set \field{gso_type} to
>  VIRTIO_NET_HDR_GSO_NONE.
> @@ -3794,9 +3875,9 @@ \subsubsection{Processing of Incoming Packets}\label{sec:Device Types / Network
>  not set VIRTIO_NET_HDR_F_RSC_INFO bit in \field{flags}.
>
>  If one of the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options have
> -been negotiated, the device SHOULD set \field{hdr_len} to a value
> -not less than the length of the headers, including the transport
> -header.
> +been negotiate and the VIRTIO_NET_HDR_GSO_UDP_TUNNEL is not set,
> +the device SHOULD set \field{hdr_len} to a value not less than
> +the length of the headers, including the transport header.
>
>  If the VIRTIO_NET_F_GUEST_CSUM feature has been negotiated, the
>  device MAY set the VIRTIO_NET_HDR_F_DATA_VALID bit in
> @@ -3814,8 +3895,9 @@ \subsubsection{Processing of Incoming Packets}\label{sec:Device Types / Network
>  if VIRTIO_NET_HDR_F_RSC_INFO bit \field{flags} is set, the
>  driver MUST NOT use the \field{csum_start} and \field{csum_offset}.
>
> -If one of the VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options have
> -been negotiated, the driver MAY use \field{hdr_len} only as a hint about the
> +If the VIRTIO_NET_HDR_GSO_UDP_TUNNEL bit is not set and one of the
> +VIRTIO_NET_F_GUEST_TSO4, TSO6 or UFO options have been negotiated,
> +the driver MAY use \field{hdr_len} only as a hint about the
>  transport header size.
>  The driver MUST NOT rely on \field{hdr_len} to be correct.
>  \begin{note}
> --
> 2.35.3
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: virtio-dev-unsubscribe@lists.oasis-open.org
> For additional commands, e-mail: virtio-dev-help@lists.oasis-open.org
>



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]