Time Stamp Injection

Reference Documentation

Platform
Intel® PAC
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.10
Napatech Software Suite: Time Stamp Injection

Introduction

A timestamp can be injected into the payload of a packet when transmitting. This can be used to measure the delay or latency of a network. The injected timestamp shows when a packet is transmitted. The receiver of the packet can compare the injected timestamp with the packet timestamp. This shows how long time the packet has been on the way from the transmitter to the receiver.

Inject the Timestamp

The timestamp is injected by the adapter when transmitting the packet. However, the timestamp injection must be enabled for each packet and decided where in the packet the timestamp should be injected. This is done by using the timestamp inject macro.
NT_NET_SET_PKT_INJECT_TIMESTAMP(packet, offset)
(See Changing timestamp inject offset mode not supported)
A pointer to the packet and an offset to where in the packet the timestamp should be injected must be supplied to the macro.
Note
Gen2 adapters: The offset has a valid range from 0 to 511 bytes from either the start of the packet or the end of the packet.
Note
Gen1 adapters: The offset has a valid range from 0 to 255 bytes from either the start of the packet or the end of the packet.
The following code is an example of how to buld a packet from scratch and inject a timestamp:
// Build the packet
NT_NET_SET_PKT_CLEAR_DESCR_EXT7((&pktNetBuf)); // Clears the packet descriptor - must be done first
NT_NET_SET_PKT_DESCR_TYPE_EXT7((&pktNetBuf)); // Sets the packet to use extended descriptor 7
NT_NET_SET_PKT_CAP_LENGTH((&pktNetBuf), currentPacketSize); // Sets the capture/stored length of the packet
// This includes the packet header and the alignment padding
NT_NET_SET_PKT_WIRE_LENGTH((&pktNetBuf), currentPacketSize);// Sets the wirelength of the packet
NT_NET_SET_PKT_CALC_L2_CRC((&pktNetBuf), 1); // Forces the FPGA to calculate a new L2 CRC
NT_NET_SET_PKT_TXPORT((&pktNetBuf), txPort); // Only necessary if transmitting on a capture adapter
// On an in-line adapter, the port is decided by the NT_NetTxGet function
NT_NET_SET_PKT_INJECT_TIMESTAMP((&pktNetBuf), 0); // Injects a timestamp at offset 0 in the packet
NT_NET_UPDATE_PKT_L2_PTR((&pktNetBuf)); // Updates the L2 pointer of the packet to match the new descriptor
if(firstPaket == 0) {
if(txTiming == NT_TX_TIMING_ABSOLUTE) {
NT_NET_SET_PKT_TXNOW((&pktNetBuf), 0);
NT_NET_SET_PKT_TXSETCLOCK((&pktNetBuf), 1);
}
else {
NT_NET_SET_PKT_TXNOW((&pktNetBuf), 1);
}
firstPaket = 1;
}
else {
NT_NET_SET_PKT_TIMESTAMP((&pktNetBuf), ((ts+99)/100)*10); // Rounds up to nearest 10 ns tick - the packet timestamp decides when
// the packet is transmitted and is different from the injected
// timestamp
NT_NET_SET_PKT_TXNOW((&pktNetBuf), 0);
}
// Creates a packet with an incrementing 32bit pattern
// Note that the packet does not contain valid MAC address, etc.
for(i=0; i<currentPacketSize/4; i++) {
*((uint32_t*)NT_NET_GET_PKT_L2_PTR((&pktNetBuf))+i) = payload++;
}
Note
In the above code example the timestamp is injected at offset 0 in the packet. This means that the beginning of the packet is overwritten by the timestamp. To prevent this, the offset must be selected with care. It is possible to select whether the offset should be counted from the start of the packet or from the end of the packet (see the description below).
Note
To inject a timestamp in the packet the extended packet descriptor must be used.
Note
If the inject offset is to large to fit into the packet, no timestamp is injected. The timestamp will not be injected outside the packet and no damage to the packet stream is done.
Note
If the inject offset is larger than the maximum range, but smaller than the packet size. The value will be masked. For a gen2 adapter the lowest 9 bit of the vallue will be used (value & 0x1FF) and for a gen1 adapter the lowest 8 bit if the value will be used (value & 0xFF).

Start Of Frame or End Of Frame Timestamp

When transmitting packets it is possible to decide whether the injected timestamp should show the time when the first or the last byte of the packet (frame) is put on the wire.
This is selected in the ntservice.ini file by setting the TimestampMethod key
Note
This setting also effects the RX timestamp when receiving packets. As with the injected timestamp, the RX timestamp shows either when the first byte is received or when the last byte is received.

Timestamp Inject Offset Mode

It is also possible to decide where the injected timestamp should be placed the payload of the packet. It is done by the NT_NET_SET_PKT_INJECT_TIMESTAMP macro and the TimestampInjectOffset parameter in the ntservice.ini file. The TimestampInjectOffset parameter specifies whether the timestamp offset should be counted from the start of the packet or from the end of the packet. This is very useful if the content of the packet must be preserved during the transmission.
To preserve the packet content, set the TimestampInjectOffset=EOF, make the packet 8 bytes larger than needed for the packet payload, and inject the timestamp at offset 0. This causes the timestamp to be injected in the 8 byte empty space without detroying the packet content.
To read the injected timestamp again it must be taken into account that the adapter adds a 4 byte CRC at the end of the packet. The injected timestamp is read at the position: Wirelength - 8 - 4.
uint64_t *pInjectedTS;
pInjectedTS = (uint64_t *)((uint8_t *)NT_NET_GET_PKT_L2_PTR((&pktNetBuf)) + NT_NET_GET_PKT_WIRE_LENGTH((&pktNetBuf)) - 12);
The offset injection mode can be controlled in the ntservice.ini file by setting the key: TimestampInjectOffset

Timestamp Method

This is a TimestampMethod "system setting" - changing the setting will affect all adapters
Section Key Values Default Description
System TimestampMethod SOF
EOF
EOF SOF = Start of Frame
EOF = End of Frame
Reception of packets (RX)
Packets can be time-stamped when the first byte is received
or when the last byte is received
Default is when the last byte is received
Transmission of packets (TX)
Packets can be time-stamped when the first byte is put on the wire
or when the last byte is put on the wire
Default is when the last byte is put on the wire
To select start of frame timestamps:
[system]
TimestampMethod = SOF
To select end of frame timestamps:
[system]
TimestampMethod = EOF

Timestamp Inject Offset

This is an TimestampInjectOffset "adapter parameter" and must be set for each adapter
Section Key Values Default Description
Adapter TimestampInjectOffset SOF
EOF
SOF SOF = Start of Frame
EOF = End of Frame
This setting pertains to transmission of packets (TX).
The setting is used for controlling the offset base used when injecting time stamps into transmitted packets.
The offset base can be either start of frame (SOF) or end of frame (EOF).
Note: The setting defines the offset base while the offset itself is a part of an extended header.
Note: Not all adapters support EOF timestamp inject mode in which case the driver will return an error.
To select start of frame offset for adapter 0:
[adapter0]
TimestampInjectOffset = SOF
To select end of frame offset for adapter 0:
[adapter0]
TimestampInjectOffset = EOF

Is Timestamp Inject Offset Mode Supported?

This mode is not supported by all adapters. Support for Changing timestamp
inject offset mode can be tested as shown below.
// Open the information stream
if ((status = NT_InfoOpen(&hInfo, "adapterinfo")) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoOpen failed. Code 0x%x = %s\n", status, errBuf);
return -1;
}
// Read adapter information for each adapter in the system
infoAdapter.cmd = NT_INFO_CMD_READ_ADAPTER_V1;
infoAdapter.u.adapter_v1.adapterNo = adapter;
if ((status = NT_InfoRead(hInfo, &infoAdapter)) != NT_SUCCESS) {
NT_ExplainError(status, errBuf, sizeof(errBuf));
fprintf(stderr, ">>> Error: NT_InfoRead failed. Code ox%x = %s\n", status, errBuf);
NT_InfoClose(hInfo);
return -1;
}
NT_InfoClose(hInfo);
if (infoAdapter.u.adapter_v1.data.tsInjectModeOffset == NT_TIMESTAMP_INJECT_OFFSET_UNSUPPORTED) {
printf("Changing time stamp inject offset mode is not supported\");
return -1;
}
Note
NT_NET_SET_PKT_INJECT_TIMESTAMP macro
if Changing timestamp inject offset mode is not supported. The offset used in the inject macro
must be in multiples of 64 bits.