|
| 1 | +# Upstreaming PTP Peer-to-Peer (P2P) Path Delay Support in SAI |
| 2 | +------------------------------------------------------------------------------- |
| 3 | + Title | Upstreaming PTP Peer-to-Peer (P2P) Path Delay Support in SAI |
| 4 | +-------------|----------------------------------------------------------------- |
| 5 | + Authors | Gurprem Singh, Michael Cutforth, Eric Lance |
| 6 | + Status | In review |
| 7 | + SAI-Version | 1.19 |
| 8 | +------------------------------------------------------------------------------- |
| 9 | + |
| 10 | +# 1. Overview & Use Case |
| 11 | + |
| 12 | +This proposal introduces support for the IEEE 1588 Peer-to-Peer (P2P) Path Delay |
| 13 | +measurement mechanism in the Switch Abstraction Interface (SAI). The primary |
| 14 | +goal of this feature is to remove the propagation time error for |
| 15 | +synchronization. |
| 16 | + |
| 17 | +Rather than calculating end-to-end latency across the entire network, each port |
| 18 | +independently measures the link propagation delay to its immediate neighbor. |
| 19 | + |
| 20 | + |
| 21 | + |
| 22 | +When a PTP event packet (such as a Sync or Follow_Up message) transits through a P2P |
| 23 | +Transparent Clock (TC), the hardware must account for two distinct delays: |
| 24 | + |
| 25 | +- Residence Time: The internal time the packet spent inside the switch |
| 26 | + (calculated as `egress_time - ingress_time`). |
| 27 | +- Propagation Time: The previously measured link delay of the ingress port |
| 28 | + (`link_delay`). |
| 29 | + |
| 30 | +By adding both the internal residence time and the ingress link propagation delay, |
| 31 | +the switch can accurately update the packet's Correction Field (CF) locally. This |
| 32 | +eliminates the impact of link propagation delay anomalies and allows downstream |
| 33 | +clocks to synchronize with incredibly high precision. |
| 34 | + |
| 35 | +# 2. Proposed SAI Spec |
| 36 | + |
| 37 | +This proposal introduces spec to offload the high-frequency exchange of |
| 38 | +IEEE 1588 Peer Delay messages to the underlying hardware. By defining a standard |
| 39 | +profile, the underlying switch hardware can be configured to autonomously |
| 40 | +transmit, receive, and timestamp Pdelay_Req and Pdelay_Resp packets across |
| 41 | +multiple ports. |
| 42 | + |
| 43 | +The control plane retains full visibility and flexibility through standard SAI |
| 44 | +attributes. The steady state link propagation delay is programmed back into the |
| 45 | +datapath via the `SAI_PORT_ATTR_LINK_DELAY` attribute which can be used to |
| 46 | +update the Correction Field (CF) of transiting PTP event packets. |
| 47 | + |
| 48 | +To cleanly separate the configuration of this hardware engine from the active |
| 49 | +physical port state, we introduce a new configuration object type, |
| 50 | +`SAI_OBJECT_TYPE_PTP_PDELAY`. This object acts as a reusable profile holding |
| 51 | +the IEEE 1588 parameters for running the autonomous peer-delay engine (such as |
| 52 | +MAC addresses, protocol, and intervals), which is then bound to physical ports. |
| 53 | + |
| 54 | +## 2.1 Pdelay Profile Attributes (SAI_OBJECT_TYPE_PTP_PDELAY) |
| 55 | + |
| 56 | +### SAI_PTP_PDELAY_ATTR_PORT_TYPE |
| 57 | + |
| 58 | +- Value Type: sai_ptp_pdelay_type_t |
| 59 | +- Flags: CREATE_AND_SET |
| 60 | +- Description: Configure as Initiator, Responder, or Both. |
| 61 | + - SAI_PTP_PDELAY_TYPE_NONE |
| 62 | + - SAI_PTP_PDELAY_TYPE_INITIATOR |
| 63 | + - SAI_PTP_PDELAY_TYPE_RESPONDER |
| 64 | + - SAI_PTP_PDELAY_TYPE_BOTH |
| 65 | + |
| 66 | +### SAI_PTP_PDELAY_ATTR_PTP_PROTOCOL |
| 67 | + |
| 68 | +- Value Type: sai_ptp_protocol_t |
| 69 | +- Flags: CREATE_AND_SET |
| 70 | +- Description: Protocol transport (IEEE 802.3, UDP/IPv4, UDP/IPv6). |
| 71 | + - SAI_PTP_PROTOCOL_NONE |
| 72 | + - SAI_PTP_PROTOCOL_UDP_IPV4 |
| 73 | + - SAI_PTP_PROTOCOL_UDP_IPV6 |
| 74 | + - SAI_PTP_PROTOCOL_IEEE8023 |
| 75 | + |
| 76 | +### SAI_PTP_PDELAY_ATTR_SRC_MAC |
| 77 | + |
| 78 | +- Value Type: sai_mac_t |
| 79 | +- Flags: CREATE_AND_SET |
| 80 | +- Description: Source MAC address used in egress Pdelay frames. |
| 81 | + |
| 82 | +### SAI_PTP_PDELAY_ATTR_L2_HEADER_LEN |
| 83 | + |
| 84 | +- Value Type: sai_uint8_t |
| 85 | +- Flags: CREATE_AND_SET |
| 86 | +- Description: Outer Layer-2 header encapsulation length in bytes. |
| 87 | + |
| 88 | +### SAI_PTP_PDELAY_ATTR_PTP_L2_HEADER |
| 89 | + |
| 90 | +- Value Type: sai_u8_list_t |
| 91 | +- Flags: CREATE_AND_SET |
| 92 | +- Description: Peer delay L2 header. The active number of header bytes in the list is specified by `SAI_PTP_PDELAY_ATTR_L2_HEADER_LEN`. |
| 93 | + |
| 94 | +### SAI_PTP_PDELAY_ATTR_NETWORK_ADDR |
| 95 | + |
| 96 | +- Value Type: sai_ip_address_t |
| 97 | +- Flags: CREATE_AND_SET |
| 98 | +- Description: Source IP address used for UDP transport encapsulation. Note: When configuring `SAI_PTP_PROTOCOL_UDP_IPV6`, an explicit IPv6 address must be specified since `@default` is `0.0.0.0`. |
| 99 | + |
| 100 | +### SAI_PTP_PDELAY_ATTR_INGRESS_VLAN_ID |
| 101 | + |
| 102 | +- Value Type: sai_uint16_t |
| 103 | +- Flags: CREATE_AND_SET |
| 104 | +- Description: Expected VLAN tag of incoming peer delay frames. |
| 105 | + |
| 106 | +### SAI_PTP_PDELAY_ATTR_DOMAIN_NUMBER |
| 107 | + |
| 108 | +- Value Type: sai_uint8_t |
| 109 | +- Flags: CREATE_AND_SET |
| 110 | +- Description: PTP Domain Number. |
| 111 | + |
| 112 | +### SAI_PTP_PDELAY_ATTR_LOG_INTERVAL |
| 113 | + |
| 114 | +- Value Type: sai_int32_t |
| 115 | +- Flags: CREATE_AND_SET |
| 116 | +- Description: Logarithmic interval of request packet transmission. |
| 117 | + |
| 118 | +### SAI_PTP_PDELAY_ATTR_TTL |
| 119 | + |
| 120 | +- Value Type: sai_uint8_t |
| 121 | +- Flags: CREATE_AND_SET |
| 122 | +- Description: Packet Time-To-Live. |
| 123 | + |
| 124 | +### SAI_PTP_PDELAY_ATTR_IP_DSCP |
| 125 | + |
| 126 | +- Value Type: sai_uint8_t |
| 127 | +- Flags: CREATE_AND_SET |
| 128 | +- Description: Packet IP DSCP priority mapping. |
| 129 | + |
| 130 | +### SAI_PTP_PDELAY_ATTR_ENABLE |
| 131 | + |
| 132 | +- Value Type: bool |
| 133 | +- Flags: CREATE_AND_SET |
| 134 | +- Description: Enable or disable the local Pdelay measurement engine. |
| 135 | + |
| 136 | +## 2.2 Port-Level Attributes |
| 137 | + |
| 138 | +### SAI_PORT_ATTR_PDELAY_INSTANCE_ID |
| 139 | + |
| 140 | +- Value Type: sai_object_id_t |
| 141 | +- Flags: CREATE_AND_SET |
| 142 | +- Description: Associates the port with a specific configuration profile. |
| 143 | + Setting this to `SAI_NULL_OBJECT_ID` detaches the profile and disables P2P |
| 144 | + processing on the physical interface. |
| 145 | + |
| 146 | +### SAI_PORT_ATTR_LINK_DELAY |
| 147 | + |
| 148 | +- Value Type: sai_int64_t |
| 149 | +- Flags: CREATE_AND_SET |
| 150 | +- Description: Used by the control plane daemon to program the calculated |
| 151 | + steady-state link propagation delay (in nanoseconds) into the physical |
| 152 | + interface's hardware registers. |
| 153 | + |
| 154 | +### SAI_PORT_ATTR_PDELAY_LINK_DELAY |
| 155 | + |
| 156 | +- Value Type: sai_int64_t |
| 157 | +- Flags: READ_ONLY |
| 158 | +- Description: Instantaneous raw link delay (in nanoseconds), computed from the latest available set of T1/T2/T3/T4 timestamps. |
| 159 | + |
| 160 | +### SAI_PORT_ATTR_PDELAY_NEIGHBOR_RATE_RATIO |
| 161 | + |
| 162 | +- Value Type: sai_int32_t |
| 163 | +- Flags: READ_ONLY |
| 164 | +- Description: Computed neighbor frequency rate ratio in 2^30 scaled fixed-point format. |
| 165 | + |
| 166 | +### SAI_PORT_ATTR_PDELAY_NEIGHBOR_PROPAGATION_DELAY |
| 167 | + |
| 168 | +- Value Type: sai_uint32_t |
| 169 | +- Flags: READ_ONLY |
| 170 | +- Description: Filtered neighbor propagation delay (in nanoseconds) computed using Neighbor Rate Ratio (NRR). |
| 171 | + |
| 172 | +### Relationship Between the Delay Attributes |
| 173 | + |
| 174 | +Three delay values are exposed on the port object. They are related, but each |
| 175 | +serves a distinct role. |
| 176 | + |
| 177 | +`SAI_PORT_ATTR_PDELAY_LINK_DELAY` is the raw, instantaneous link delay derived |
| 178 | +from the most recent peer delay timestamp exchange. It reflects a single |
| 179 | +measurement. It is neither corrected for the frequency offset between the local |
| 180 | +and neighbor clocks nor smoothed across successive exchanges, so it is expected |
| 181 | +to vary from one measurement to the next. It is primarily useful for |
| 182 | +diagnostics and for observing the behavior of the link over time. |
| 183 | + |
| 184 | +`SAI_PORT_ATTR_PDELAY_NEIGHBOR_PROPAGATION_DELAY` is the steady-state |
| 185 | +propagation delay. It is derived from the same timestamp exchanges, but the |
| 186 | +interval measured by the neighbor is first normalized using the Neighbor Rate |
| 187 | +Ratio to compensate for the frequency difference between the two clocks, and the |
| 188 | +result is filtered across successive exchanges. This is the value intended for |
| 189 | +steady-state use, computed as described in IEEE Std 802.1AS. |
| 190 | + |
| 191 | +`SAI_PORT_ATTR_LINK_DELAY` is the delay value the NOS programs into the device |
| 192 | +for datapath use which can be used to update the correction field of transiting |
| 193 | +PTP event packets. |
| 194 | + |
| 195 | +The first two attributes are read-only measurement outputs produced by the |
| 196 | +hardware peer delay engine. The third is a control plane input. Keeping them |
| 197 | +separate allows the NOS to apply its own filtering, hold-over behavior, or |
| 198 | +static asymmetry correction before committing a value to the datapath, rather |
| 199 | +than requiring the datapath to consume a raw measurement directly. It also |
| 200 | +allows the delay to be supplied by the NOS on links where the hardware peer |
| 201 | +delay engine is not in use. |
| 202 | + |
| 203 | +## 2.3 Switch-Level Global Attributes |
| 204 | + |
| 205 | +### SAI_SWITCH_ATTR_CLOCK_ID |
| 206 | + |
| 207 | +- Value Type: sai_u8_list_t |
| 208 | +- Flags: CREATE_AND_SET |
| 209 | +- Description: Specifies the global clock identity of the PTP platform. |
| 210 | + An 8-octet array (`uint8_t[8]`) in network byte order as specified in IEEE |
| 211 | + Std 1588-2019. |
| 212 | + |
| 213 | +### SAI_SWITCH_ATTR_PTP_PDELAY_MAX_PORTS |
| 214 | + |
| 215 | +- Value Type: sai_uint16_t |
| 216 | +- Flags: CREATE_AND_SET |
| 217 | +- Description: Configures the maximum number of ports allocated for PTP |
| 218 | + peer-delay concurrently in firmware. |
| 219 | + |
| 220 | +### SAI_SWITCH_ATTR_MAX_SUPPORTED_PTP_PDELAY_PORTS |
| 221 | + |
| 222 | +- Value Type: sai_uint16_t |
| 223 | +- Flags: READ_ONLY |
| 224 | +- Description: Queries the platform's maximum hardware capacity limit of ports |
| 225 | + supporting peer delay exchanges. |
| 226 | + |
| 227 | +### SAI_SWITCH_ATTR_PTP_PDELAY_IS_TWO_STEP |
| 228 | + |
| 229 | +- Value Type: bool |
| 230 | +- Flags: CREATE_AND_SET |
| 231 | +- Default: false |
| 232 | +- Description: Specifies whether the hardware PTP peer-delay engine operates in |
| 233 | + two-step mode (transmitting Pdelay_Resp_Follow_Up messages) or one-step mode |
| 234 | + (embedding turnaround time directly into Pdelay_Resp messages) during peer |
| 235 | + delay message exchanges. |
| 236 | + |
| 237 | + **Significance & Relationship to `SAI_PORT_ATTR_PTP_MODE`:** |
| 238 | + Per IEEE 1588, end-to-end event message forwarding (`Sync`, `Delay_Req`) and |
| 239 | + link-local peer delay measurement (`Pdelay_Req`, `Pdelay_Resp`, |
| 240 | + `Pdelay_Resp_Follow_Up`) are independent protocol mechanisms. |
| 241 | + `SAI_SWITCH_ATTR_PTP_PDELAY_IS_TWO_STEP` applies strictly to the hardware peer |
| 242 | + delay engine (`Pdelay_Resp` / `Pdelay_Resp_Follow_Up`), whereas |
| 243 | + `SAI_PORT_ATTR_PTP_MODE` governs one-step vs. two-step timestamping for |
| 244 | + transiting PTP event packets. Keeping these configurations independent allows |
| 245 | + a switch to forward transit event packets as a one-step Transparent Clock |
| 246 | + (`SAI_PORT_ATTR_PTP_MODE == SAI_PORT_PTP_MODE_SINGLE_STEP_TIMESTAMP`) while |
| 247 | + performing two-step link-local peer delay exchanges |
| 248 | + (`SAI_SWITCH_ATTR_PTP_PDELAY_IS_TWO_STEP == true`), or vice versa, based on |
| 249 | + link partner interoperability and deployment requirements. |
| 250 | + |
| 251 | +## 2.4 PTP Pdelay Port Statistics |
| 252 | + |
| 253 | +### SAI_PORT_STAT_PTP_PDELAY_TX_REQ_COUNT |
| 254 | + |
| 255 | +- Description: Count of transmitted Peer Delay Request packets. |
| 256 | + |
| 257 | +### SAI_PORT_STAT_PTP_PDELAY_RX_REQ_COUNT |
| 258 | + |
| 259 | +- Description: Count of received Peer Delay Request packets. |
| 260 | + |
| 261 | +### SAI_PORT_STAT_PTP_PDELAY_TX_RESP_COUNT |
| 262 | + |
| 263 | +- Description: Count of transmitted Peer Delay Response packets. |
| 264 | + |
| 265 | +### SAI_PORT_STAT_PTP_PDELAY_RX_RESP_COUNT |
| 266 | + |
| 267 | +- Description: Count of received Peer Delay Response packets. |
| 268 | + |
| 269 | +### SAI_PORT_STAT_PTP_PDELAY_TX_RESP_FOLLOWUP_COUNT |
| 270 | + |
| 271 | +- Description: Count of transmitted Peer Delay Response Follow-Up packets. |
| 272 | + |
| 273 | +### SAI_PORT_STAT_PTP_PDELAY_RX_RESP_FOLLOWUP_COUNT |
| 274 | + |
| 275 | +- Description: Count of received Peer Delay Response Follow-Up packets. |
| 276 | + |
| 277 | +### SAI_PORT_STAT_PTP_PDELAY_RESP_TIMEOUT_COUNT |
| 278 | + |
| 279 | +- Description: Count of Peer Delay Response timeouts. |
| 280 | + |
| 281 | +### SAI_PORT_STAT_PTP_PDELAY_RESP_FOLLOWUP_TIMEOUT_COUNT |
| 282 | + |
| 283 | +- Description: Count of Peer Delay Response Follow-Up timeouts. |
| 284 | + |
| 285 | +## 2.5 Coexistence with Existing PTP Model |
| 286 | + |
| 287 | +The existing PTP model is not deprecated: |
| 288 | + |
| 289 | +- **Hardware Offload Mode:** Active when `SAI_PORT_ATTR_PDELAY_INSTANCE_ID` is set to a valid profile. Peer delay packets are processed in hardware without trapping to the CPU, and the new delay attributes are active. |
| 290 | +- **Existing Mode:** When `SAI_PORT_ATTR_PDELAY_INSTANCE_ID` is `SAI_NULL_OBJECT_ID`, `SAI_PORT_ATTR_PTP_PEER_MEAN_PATH_DELAY` can continue to be used. |
| 291 | + |
| 292 | +### Model Applicability of New Attributes |
| 293 | + |
| 294 | +- **Attributes Applicable to Both Models:** |
| 295 | + - `SAI_PORT_ATTR_LINK_DELAY`: Programs the datapath link delay in signed nanoseconds; can be used whether delay is calculated via hardware offload or by the NOS in software (e.g., if a signed value needs to be programmed instead of unsigned `SAI_PORT_ATTR_PTP_PEER_MEAN_PATH_DELAY`). |
| 296 | + - *(Note: All new switch-level attributes introduced in this proposal apply only to the hardware offload model).* |
| 297 | + |
| 298 | +- **Attributes Inactive When Hardware Offload is Enabled (`SAI_PORT_ATTR_PDELAY_INSTANCE_ID != SAI_NULL_OBJECT_ID`):** |
| 299 | + - `SAI_PORT_ATTR_PTP_PEER_MEAN_PATH_DELAY`: Does not take effect on the port (datapath delay is driven by `SAI_PORT_ATTR_LINK_DELAY`). |
| 300 | + |
| 301 | +- **Attributes Inactive When Existing Software Trap Mode is Active (`SAI_PORT_ATTR_PDELAY_INSTANCE_ID == SAI_NULL_OBJECT_ID`):** |
| 302 | + - Hardware offload measurement attributes (`SAI_PORT_ATTR_PDELAY_LINK_DELAY`, `SAI_PORT_ATTR_PDELAY_NEIGHBOR_RATE_RATIO`, `SAI_PORT_ATTR_PDELAY_NEIGHBOR_PROPAGATION_DELAY`) and statistics (`SAI_PORT_STAT_PTP_PDELAY_*`) do not take effect. |
| 303 | + - Switch-level offload attributes (`SAI_SWITCH_ATTR_CLOCK_ID`, `SAI_SWITCH_ATTR_PTP_PDELAY_MAX_PORTS`, `SAI_SWITCH_ATTR_MAX_SUPPORTED_PTP_PDELAY_PORTS`, `SAI_SWITCH_ATTR_PTP_PDELAY_IS_TWO_STEP`) have no effect on port packet processing. |
| 304 | + |
| 305 | +### Interaction & Precedence: `SAI_PORT_ATTR_LINK_DELAY` vs. `SAI_PORT_ATTR_PTP_PEER_MEAN_PATH_DELAY` |
| 306 | + |
| 307 | +In software (non-offload) mode (`SAI_PORT_ATTR_PDELAY_INSTANCE_ID == SAI_NULL_OBJECT_ID`), both attributes configure the **same underlying datapath property**: the ingress link propagation delay added to the PTP event packet Correction Field (CF) alongside residence time. |
| 308 | + |
| 309 | +- **Aliasing:** Both `SAI_PORT_ATTR_LINK_DELAY` (`sai_int64_t`) and `SAI_PORT_ATTR_PTP_PEER_MEAN_PATH_DELAY` (`sai_uint32_t`) are aliases for the same underlying per-port datapath delay configuration. `SAI_PORT_ATTR_LINK_DELAY` extends the representation to signed 64-bit to support negative asymmetry compensation per IEEE 1588 / 802.1AS. |
| 310 | +- **Precedence in Non-Offload Mode:** |
| 311 | + - Setting either attribute updates the active link delay on the port (**last-write-wins**). |
| 312 | + - Applications SHOULD use `SAI_PORT_ATTR_LINK_DELAY` exclusively and avoid mixing writes to both attributes on the same port. |
| 313 | +- **Get Semantics:** |
| 314 | + - Calling `sai_get_port_attribute` on either attribute returns the active datapath delay value in that attribute's respective type (`sai_int64_t` or `sai_uint32_t`). |
| 315 | +- **In Hardware Offload Mode (`SAI_PORT_ATTR_PDELAY_INSTANCE_ID != SAI_NULL_OBJECT_ID`):** |
| 316 | + - Only `SAI_PORT_ATTR_LINK_DELAY` takes effect in the datapath. `SAI_PORT_ATTR_PTP_PEER_MEAN_PATH_DELAY` is inactive and ignored. |
| 317 | + |
| 318 | +## 3. API Workflow and Example |
| 319 | + |
| 320 | +3.1 The global PTP clock identity must be initialized on the switch. |
| 321 | + |
| 322 | +```c |
| 323 | +sai_attribute_t attr; |
| 324 | +attr.id = SAI_SWITCH_ATTR_CLOCK_ID; |
| 325 | +attr.value.u8list.count = 8; |
| 326 | +attr.value.u8list.list = my_clock_id; |
| 327 | +sai_switch_api->set_switch_attribute(switch_id, &attr); |
| 328 | +``` |
| 329 | +
|
| 330 | +3.2 Creating a Pdelay Profile |
| 331 | +An application creates a reusable Pdelay profile |
| 332 | +configuration. |
| 333 | +
|
| 334 | +```c |
| 335 | +sai_attribute_t attr_list[3]; |
| 336 | +attr_list[0].id = SAI_PTP_PDELAY_ATTR_PORT_TYPE; |
| 337 | +attr_list[0].value.s32 = SAI_PTP_PDELAY_TYPE_BOTH; |
| 338 | +attr_list[1].id = SAI_PTP_PDELAY_ATTR_LOG_INTERVAL; |
| 339 | +attr_list[1].value.s32 = -3; // 8 packets per second |
| 340 | +attr_list[2].id = SAI_PTP_PDELAY_ATTR_ENABLE; |
| 341 | +attr_list[2].value.booldata = true; |
| 342 | +
|
| 343 | +sai_object_id_t pdelay_id; |
| 344 | +sai_ptp_pdelay_api->create_ptp_pdelay(&pdelay_id, switch_id, 3, attr_list); |
| 345 | +``` |
| 346 | + |
| 347 | +3.3 Binding Profile to a Port |
| 348 | +The profile is bound to a physical interface to |
| 349 | +activate hardware P2P processing. |
| 350 | + |
| 351 | +```c |
| 352 | +sai_attribute_t attr; |
| 353 | +attr.id = SAI_PORT_ATTR_PDELAY_INSTANCE_ID; |
| 354 | +attr.value.oid = pdelay_id; |
| 355 | +sai_port_api->set_port_attribute(port_id, &attr); |
| 356 | +``` |
0 commit comments