|
| 1 | +\section{Cyphal/UDP}\label{sec:transport_udp} |
| 2 | + |
| 3 | +\hyphenation{Cyphal/UDP} % Disable hyphenation. |
| 4 | + |
| 5 | +\subsection{Overview} |
| 6 | + |
| 7 | +This section specifies a concrete transport based on the UDP/IPv4 protocol\footnote{% |
| 8 | + Support for IPv6 may appear in a future revision of this specification. |
| 9 | +} as specified in IETF RFC~768. |
| 10 | +Cyphal/UDP is the recommended transport for intravehicular Ethernet networks with complex topologies, |
| 11 | +which may be switched, multi-drop, or mixed, and can be built with standards-compliant commercial |
| 12 | +off-the-shelf networking equipment and software. |
| 13 | + |
| 14 | +A UDP datagram represents a single Cyphal transport frame. |
| 15 | +The maximum subject-ID supported by Cyphal/UDP is $2^{23}-1 = 8388607$, which matches the addressable space |
| 16 | +of the IPv4 multicast MAC layer; see section~\ref{sec:transport_udp_endpoints} for details. |
| 17 | +The maximum transfer payload size is $2^{32}-1$ bytes. |
| 18 | +Implementations shall provide a UDP/IPv4 stack with IGMP v2 (or later) and passive ARP support. |
| 19 | + |
| 20 | +A Cyphal/UDP node is identified on the network by a $64$-bit \emph{node UID}, which shall be globally unique. |
| 21 | +The UID enables a node to freely change its IP address or migrate between network interfaces at runtime. |
| 22 | +A common choice is an EUI-64 identifier, optionally drawn randomly per startup for short-lived software nodes. |
| 23 | + |
| 24 | +\subsection{Datagram addressing}\label{sec:transport_udp_endpoints} |
| 25 | + |
| 26 | +\subsubsection{Multicast} |
| 27 | + |
| 28 | +Multicast transfers carry one Cyphal subject each. |
| 29 | +A subject with subject-ID $s$ shall be mapped to the IPv4 multicast group |
| 30 | +$239.0.0.0 \;|\; (s \;\&\; \text{0x7FFFFF})$\footnote{% |
| 31 | + $|$ denotes bitwise OR, $\&$ bitwise AND. |
| 32 | +} on the reserved UDP destination port $9382$. |
| 33 | +The $9$ most significant bits of the multicast address are thus fixed at $11101111\,0_2$. |
| 34 | + |
| 35 | +\begin{remark} |
| 36 | + Freezing the $9$ most significant bits of the multicast group address confines address variability to |
| 37 | + the $23$ least significant bits. This is necessary because the IPv4 Ethernet MAC layer does not |
| 38 | + differentiate beyond the $23$ least significant bits of the multicast group address |
| 39 | + (RFC~1112 section~6.4): addresses that differ only in the $9$ most significant bits alias at the MAC |
| 40 | + layer, which is unacceptable in a real-time system. |
| 41 | + Without this constraint, an engineer designing a network might inadvertently create a configuration |
| 42 | + that causes MAC-layer collisions that are difficult to detect. |
| 43 | +\end{remark} |
| 44 | + |
| 45 | +Sources of Cyphal/UDP multicast traffic \emph{should} set the IP packet TTL to $16$ or higher. |
| 46 | + |
| 47 | +\begin{remark} |
| 48 | + RFC~1112 prescribes a default TTL of $1$, which is not sufficient because Cyphal/UDP networks may |
| 49 | + exceed a diameter of one hop. |
| 50 | +\end{remark} |
| 51 | + |
| 52 | +\subsubsection{Unicast} |
| 53 | + |
| 54 | +Cyphal/UDP does not reserve a dedicated endpoint for unicast delivery. |
| 55 | +A unicast transfer shall be addressed to the recipient's UDP/IP endpoint as observed on an earlier |
| 56 | +datagram originated by that recipient on the same interface. |
| 57 | +A receiving node is expected to retain the $(\text{interface}, \text{source endpoint})$ observation for |
| 58 | +each remote UID in order to enable subsequent unicast replies. |
| 59 | + |
| 60 | +\begin{remark} |
| 61 | + This convention allows Cyphal/UDP nodes to change their IP addresses and even migrate between |
| 62 | + network interfaces dynamically, provided they continue to publish on subjects |
| 63 | + (section~\ref{sec:transport_subject_id_ranges}) so that their peers can rediscover them. |
| 64 | +\end{remark} |
| 65 | + |
| 66 | +\subsection{QoS}\label{sec:transport_udp_qos} |
| 67 | + |
| 68 | +The DSCP\footnote{RFC~2474} field of outgoing IP packets \emph{should} be populated based on the Cyphal |
| 69 | +transfer priority level of the corresponding transfer. |
| 70 | +Implementations \emph{should} provide a means for the integrator to configure the mapping from Cyphal |
| 71 | +priority to DSCP per node. |
| 72 | +The integrator \emph{shall} ensure that the applied mapping is consistent with the QoS policies |
| 73 | +implemented in the network\footnote{% |
| 74 | + This requirement is intended to prevent inconsistent QoS treatment of Cyphal/UDP traffic and priority |
| 75 | + inversion. RFC~4594 provides a starting point for the design of network QoS policies; |
| 76 | + RFC~8837 provides a useful reference for real-time traffic classes. |
| 77 | +}. |
| 78 | + |
| 79 | +In the absence of an integrator-provided mapping, a conforming implementation \emph{should} default to the |
| 80 | +conservative mapping shown in table~\ref{table:transport_udp_priority}, which places all Cyphal/UDP traffic |
| 81 | +into the Default Forwarding class. This default is safe in that it does not depend on any network QoS |
| 82 | +configuration; where QoS differentiation is desired, the integrator is expected to configure the mapping |
| 83 | +explicitly. |
| 84 | + |
| 85 | +\begin{CyphalSimpleTable}{ |
| 86 | + Default mapping from Cyphal priority level to DSCP\label{table:transport_udp_priority} |
| 87 | +}{|l l l l|} |
| 88 | + Cyphal priority & Header priority value & DSCP class & DSCP value \\ |
| 89 | + Exceptional & 0 & DF & 0 \\ |
| 90 | + Immediate & 1 & DF & 0 \\ |
| 91 | + Fast & 2 & DF & 0 \\ |
| 92 | + High & 3 & DF & 0 \\ |
| 93 | + Nominal & 4 & DF & 0 \\ |
| 94 | + Low & 5 & DF & 0 \\ |
| 95 | + Slow & 6 & DF & 0 \\ |
| 96 | + Optional & 7 & DF & 0 \\ |
| 97 | +\end{CyphalSimpleTable} |
| 98 | + |
| 99 | +\subsection{Datagram payload format}\label{sec:transport_udp_payload} |
| 100 | + |
| 101 | +Each UDP datagram payload begins with a fixed-size $32$-byte Cyphal/UDP header followed by the transport |
| 102 | +frame payload, which is opaque to the transport. The header layout is shown in the following snippet in |
| 103 | +pseudo-DSDL notation; multi-byte integers are little-endian. |
| 104 | + |
| 105 | +\begin{samepage} |
| 106 | +\begin{minted}{python} |
| 107 | +uint5 version # =2 in this version. |
| 108 | +uint3 priority # 0=highest, 7=lowest. |
| 109 | + |
| 110 | +void5 # Send zero, ignore on reception. |
| 111 | +uint3 incompatibility # Send zero, drop frame if nonzero. |
| 112 | + |
| 113 | +uint48 transfer_id # For multi-frame reassembly and deduplication. |
| 114 | +uint64 sender_uid # The 64-bit UID of the originating node. |
| 115 | + |
| 116 | +uint32 frame_payload_offset # Offset of this frame's payload within the transfer payload. |
| 117 | +uint32 transfer_payload_size # Total transfer payload size, identical for every frame of the transfer. |
| 118 | + |
| 119 | +uint32 prefix_crc32c # crc32c(transfer_payload[0 : frame_payload_offset + frame_payload_size]) |
| 120 | +uint32 header_crc32c # crc32c(first 28 bytes of this header) |
| 121 | + |
| 122 | +# Header size is 32 bytes; the transport frame payload follows and is opaque to the protocol. |
| 123 | +\end{minted} |
| 124 | +\end{samepage} |
| 125 | + |
| 126 | +All frames belonging to the same transfer shall carry identical values of \texttt{priority}, |
| 127 | +\texttt{transfer\_id}, \texttt{sender\_uid}, and \texttt{transfer\_payload\_size}. |
| 128 | +A receiver shall discard any frame whose \texttt{version} field does not equal the expected value, |
| 129 | +and any frame whose \texttt{incompatibility} field is non-zero. |
| 130 | +Frames may arrive out-of-order and may interleave with neighboring transfers; |
| 131 | +implementations shall cope with both conditions. |
| 132 | + |
| 133 | +The CRC function is \textbf{CRC-32C (Castagnoli)}: polynomial $0x1EDC6F41$, initial value $0xFFFFFFFF$, |
| 134 | +input reflected, output reflected, final XOR $0xFFFFFFFF$. |
| 135 | +The \texttt{header\_crc32c} field protects the first $28$ bytes of the header and is verified |
| 136 | +independently on every received frame, allowing malformed frames to be rejected without parsing the body. |
| 137 | +The \texttt{prefix\_crc32c} field holds a running CRC computed over the accumulated transfer payload bytes |
| 138 | +from offset zero up to and including the current frame's payload. On single-frame transfers |
| 139 | +(\texttt{frame\_payload\_offset} equal to zero and \texttt{frame\_payload\_size} equal to |
| 140 | +\texttt{transfer\_payload\_size}) it therefore doubles as the end-to-end transfer integrity check; |
| 141 | +on multi-frame transfers, the receiver uses it to validate the reassembled transfer as each frame is |
| 142 | +admitted and to detect errors early. |
| 143 | + |
| 144 | +\subsection{Maximum transmission unit}\label{sec:transport_udp_mtu} |
| 145 | + |
| 146 | +The maximum transmission unit (MTU) is defined as the maximum size of a UDP/IP datagram payload, |
| 147 | +inclusive of the $32$-byte Cyphal/UDP header. |
| 148 | + |
| 149 | +Because Cyphal provides native segmentation and reassembly (section~\ref{sec:transport}), |
| 150 | +nodes emitting Cyphal/UDP traffic \emph{shall not} rely on IP fragmentation; |
| 151 | +implementations shall limit the size of the UDP payload accordingly\footnote{% |
| 152 | + This requirement is consistent with RFC~8085 and RFC~8900. Transfers larger than the MTU limit shall |
| 153 | + be emitted as multi-frame transfers. The preference for Cyphal segmentation over IP fragmentation |
| 154 | + removes the $\sim$65~KiB transfer size ceiling imposed by the UDP protocol and permits preemption of |
| 155 | + long transfers by higher-priority traffic. |
| 156 | +}. |
| 157 | +Support for IP fragmentation is optional for receivers. |
| 158 | +Intermediate network equipment may perform IP fragmentation as long as the behavior is opaque to the |
| 159 | +Cyphal/UDP end systems. |
| 160 | + |
| 161 | +In multi-frame transfers, all frames except the last shall carry the same amount of frame payload. |
| 162 | +The last frame shall carry a non-zero amount of frame payload not greater than that of the preceding |
| 163 | +frames\footnote{% |
| 164 | + This constraint enables efficient reassembly of multi-frame transfers with frames arriving |
| 165 | + out-of-order, including the case of frame interleaving between adjacent transfers. |
| 166 | +}. |
| 167 | + |
| 168 | +\subsection{Transfer-ID initialization}\label{sec:transport_udp_transfer_id} |
| 169 | + |
| 170 | +The sender shall assign a unique $48$-bit \texttt{transfer\_id} to every transfer it emits and shall |
| 171 | +increment the counter once per emitted transfer. |
| 172 | +The initial value of the counter \emph{shall} be drawn randomly at each node startup such that it is |
| 173 | +unlikely to coincide with any transfer-ID value recently used by the same sender UID. |
| 174 | +A uniformly-distributed $48$-bit random draw provides sufficient entropy for this purpose with |
| 175 | +overwhelming probability. |
| 176 | + |
| 177 | +Random initialization obviates the need for a transfer-ID timeout at the receiver: because sender UIDs |
| 178 | +are globally unique and the transfer-ID counter does not wrap within the effective lifetime of the |
| 179 | +protocol, stale transfers from an earlier epoch do not collide with fresh ones. |
| 180 | +This simplifies the receive pipeline, but it places a correctness requirement on the quality of the |
| 181 | +random source used to seed the counter. |
| 182 | + |
| 183 | +The random source used to seed the transfer-ID counter \emph{shall} produce an initial state that is |
| 184 | +distinct across reboots in quick succession, and \emph{should} mix the seed with the local node UID for |
| 185 | +additional entropy. |
| 186 | +A hardware true-random generator is preferred. |
| 187 | +In its absence, a well-seeded pseudorandom generator is acceptable; suitable seed sources for embedded |
| 188 | +systems without a TRNG include: |
| 189 | + |
| 190 | +\begin{itemize} |
| 191 | + \item A counter held in battery-backed memory or a \texttt{.noinit} RAM section that survives resets. |
| 192 | + \item A hash of uninitialized SRAM contents sampled at startup. |
| 193 | + \item Sampled ADC or clock noise. |
| 194 | + \item The current value of an RTC combined with a persistent counter. |
| 195 | +\end{itemize} |
| 196 | + |
| 197 | +A single well-seeded random draw at startup is sufficient; the counter itself need not come from a |
| 198 | +cryptographic source once initialized. |
| 199 | + |
| 200 | +\subsection{Real-time and resource-constrained systems} |
| 201 | + |
| 202 | +Real-time or resource-constrained systems may implement Cyphal/UDP using a custom UDP/IP and IGMP stack |
| 203 | +with a reduced feature set; in particular, they may omit support for IP fragmentation and ICMP. |
| 204 | + |
| 205 | +Networking equipment connected to such systems is \emph{recommended} to suppress ICMP emission, because: |
| 206 | + |
| 207 | +\begin{enumerate} |
| 208 | + \item ICMP traffic increases network load and may perturb the timing of the system; in some |
| 209 | + deployments it can also be considered an attack vector. |
| 210 | + \item Cyphal/UDP nodes are not required to support ICMP and may therefore be unable to process |
| 211 | + incoming ICMP messages. |
| 212 | +\end{enumerate} |
0 commit comments