4GA Test and Measurement

Reference Documentation

product_line_custom
Intel® PAC
Napatech SmartNIC
category
Reference Information
Napatech Software Suite: 4GA Test and Measurement

Introduction

The 4GA Test and Measurement FPGAs have the following features for packet transmission via TX network streams:

  • Per packet FCS control, i.e. insert good FCS, insert bad FCS, no FCS change
  • Per packet L3 and L4 checksum control, i.e. insert good checksum, insert bad checksum, no checksum change, insert zero (UDP)
  • Per packet time stamp injection control, i.e. insert time stamp, do not insert time stamp

The following sections will describe how these features are used.

Feature mask

The Info Stream can be used to check whether a specific feature is available. The code example below shows how to check for the time stamp inject feature.

// Open the infostream.
if((status = NT_InfoOpen(&hInfo, "tsi")) != NT_SUCCESS) {
fprintf(stderr, "NT_InfoOpen() failed: %s\n", errorBuffer);
return -1;
}
// Check whether or not time stamp inject is supported on the defined port
infoRead.cmd = NT_INFO_CMD_READ_PORT_V9;
infoRead.u.port_v9.portNo = PORT;
if((status = NT_InfoRead(hInfo, &infoRead)) != NT_SUCCESS) {
fprintf(stderr, "NT_InfoRead() failed: %s\n", errorBuffer);
NT_InfoClose(hInfo);
return -1;
}
if (infoRead.u.port_v9.data.capabilities.featureMask & NT_PORT_FEATURE_INJECT_TX_TS) {
printf(stderr, "Time stamp inject is possible on the selected port %d\n", PORT);
}
NT_InfoClose(hInfo);

See net/timestamp_inject/timestamp_inject_example.cpp for more details.

General principle

To use these features open a TX Network Stream with DescriptorMode configured to be one of the dynamic descriptors using NT_NetTxOpenAttrSetDescriptorMode.
Before the NT_NetTxOpen_Attr call, the application must enable the specific feature and configure which bit(s) in the dynamic descriptor are used as command bit(s) for the feature.
The code example below shows how to open a TX network stream with the time stamp inject feature enabled.

NT_NetTxOpenAttrSetName(&txAttr, "Time stamp inject");
NT_NetTxOpenAttrSetPortMask(&txAttr, 0x1 << txPort);
status = NT_NetTxOpenAttrSetTxtDescriptorPosTimestampInject(&txAttr, true, 137); // Notice: Bit 137 configured as command bit
if (status != NT_SUCCESS)
{
fprintf(stderr, "NT_NetTxOpenAttrSetTxtDescriptorPosTimestampInject failed: %s\n", errorBuffer);
exit(1);
}
status = NT_NetTxOpen_Attr(&hNetTx, &txAttr);
if (status != NT_SUCCESS) {
fprintf(stderr, "NT_NetTxOpen() failed: %s\n", errorBuffer);
exit(1);
}
// The TX network stream is ready for use

The NT_NetTxOpenAttrSetTxtDescriptorPosTimestampInject call enables the time stamp inject feature and configures descriptor bit number 137 to be the command-bit for controlling time stamp inject, i.e. when transmitting packets using the stream, the application can control whether a TX time stamp shall be injected by setting descriptor bit number 137 to either 1 or 0. If descriptor bit number 137 is set to 1, a time stamp will be injected - if set to 0, no time stamp will be injected.
The other features, i.e. FCS control per packet and L3 & L4 checksum control per packet, have similar API calls for enabling the features and configuring the position of the related descriptor command bits. This is described in the following sections.

TX dynamic descriptors

The PacketDescriptor section describes the dynamic descriptors. Some fields in the structs are used by the TX engine in order to transmit the packets correctly. Other fields are by default unused by the TX engine. An application can use these by-default-unused fields to hold the command bits for the test & measurement features.
An application shall avoid placing the feature command-bits in the following fields as these are used by the TX engine for other purposes:

  • capLength: The length of the packet incl. descriptor.
  • wireLength: The length of the packet. DYN3 only.
  • descrFormat: The descriptor type.
  • descrLength: The length of the descriptor in bytes.
  • ntDynDescr: Set to 1 to identify this descriptor as a dynamic descriptor.
  • offset0: Bytes offset to start of Layer 3 header (see section below)
  • offset1: Bytes offset to start of Layer 4 header (see section below)

The NTAPI includes functions and macros that assist the application in setting most of these fields correctly.

When using a TX network stream in packet mode, the NT_NetTxGet function will return a buffer with pre-filled capLength, wireLength, descrFormat, descrLength and ntDynDesr. So the application only needs to set offset0, offset1 (see section below) and the feature-cmd bits. See net/timestamp_inject/timestamp_inject_example.cpp and net/checksum/checksum_example.cpp for more details.

When using a TX network stream in segment mode, the macros NT_NET_SET_PKT_CLEAR_DESCR_DYN3, NT_NET_SET_PKT_DESCR_TYPE_DYN3 and NT_NET_SET_PKT_CAP_LENGTH_NOALIGN serve the same purpose. See net/transmit_segment_dyn_descr/transmit_segment_dyn_descr_example.cpp for more details.

L3 & L4 offsets

Applications that use the

  • Per packet L3 and L4 checksum control
  • Per packet time stamp injection control with dynamic offset set to either start of Layer 3 or start of Layer 4

must set the dynamic descriptor field offset0 to the byte offset of Layer 3 and offset1 to the byte offset of Layer 4.

If the above features are not used, the TX engine will ignore offset0 and offset1 and, consequently, the application does not need to set those fields.

FCS control

By default the TX engine will calculate and insert a correct FCS in every transmitted frame.

The "Per packet FCS control" enables the application to control how the TX engine shall handle the FCS field per packet. The application can instruct the TX engine to insert a correct FCS, a bad FCS or leave the FCS field unchanged.

The feature is enabled using the NT_NetTxOpenAttrSetTxtDescriptorPosFcs function call. The function call also configures which descriptor bits hold the FCS command.

The command field is 2 bit wide with the following encoding:

  • 0 : Insert correct FCS
  • 1 : Insert bad FCS
  • 2 : Reserved
  • 3 : Leave FCS unchanged

See net/timestamp_inject/timestamp_inject_example.cpp for more details.

L3 & L4 checksum control

By default the TX engine will not calculate and insert Layer 3 and Layer 4 checksums.
The "Per packet L3/L4 checksum control" can be enabled using the NT_NetTxOpenAttrSetDescriptorPosChecksumCmd call. The function call also configures which descriptor bits hold the L3/L4 checksum command.

The command field is 5 bit wide and is divided into two subfields.

Bits [4:3] control the Layer 3 (aka IPv4) checksum:

  • 0, 1 : Do nothing,
  • 2 : Insert BAD checksum in IPv4 header
  • 3 : Insert GOOD checksum in IPv4 header

Bits [2:0] control the Layer 4 (aka UDP/TCP) checksum:

  • 0, 1 : Do nothing
  • 2 : Insert BAD checksum in TCP/UDP header
  • 3 : Insert GOOD checksum in TCP/UDP header
  • 4 : Insert GOOD checksum in TCP header and a value of ZERO in UDP header
  • 5 : Insert GOOD checksum in TCP header and a value of ZERO in UDP header when IP is IPv4
  • 6 : Insert GOOD checksum in TCP/UDP header and a value of ZERO in UDP header when part of a tunnel
  • 7 : Insert GOOD checksum in TCP/UDP header and a value of ZERO in UDP header when IP is IPv4 and part of a tunnel

Besides configuring and setting the checksum command bits, the application must also set a frame-type field. The location of the frame-type field is configured using NT_NetTxOpenAttrSetDescriptorPosFrameType. The frame-type field is 4 bits wide and is a combination of IPv4/Ipv6/Other, UDP/TCP/Other, and whether the protocol is tunneled or not.

Bits [3:0] of frame-type:

  • Bit [0]:
    • Value 0 : Not tunneled
    • Value 1 : Tunneled
  • Bit [1]:
    • Value 0 : IPv4 or other
    • Value 1 : IPv6
  • Bit [3:2]:
    • Value 0 : Other
    • Value 1 : TCP
    • Value 2 : UDP
    • Value 3 : Reserved

With the bit values above, the following enum can be created:

enum FrameType {
FRAME_TYPE_IPV4_TCP = 0x0 | 0x0 | 0x4,
FRAME_TYPE_IPV4_UDP = 0x0 | 0x0 | 0x8,
FRAME_TYPE_IPV6_TCP = 0x0 | 0x2 | 0x4,
FRAME_TYPE_IPV6_UDP = 0x0 | 0x2 | 0x8,
FRAME_TYPE_IPV4_TCP_TUNNELED = 0x1 | 0x0 | 0x4,
FRAME_TYPE_IPV4_UDP_TUNNELED = 0x1 | 0x0 | 0x8,
FRAME_TYPE_IPV6_TCP_TUNNELED = 0x1 | 0x2 | 0x4,
FRAME_TYPE_IPV6_UDP_TUNNELED = 0x1 | 0x2 | 0x8,
};

See net/checksum/checksum_example.cpp for more details.

Time stamp control

By default the TX engine will not insert TX time stamps in the transmitted packets.

There are two ways to enable the feature:

  • The ini-setting TimestampInjectAlways can be set to the value "true". In this case a time stamp will be inserted in all packets regardless of any other settings.
  • The feature can be enabled by the NT_NetTxOpenAttrSetTxtDescriptorPosTimestampInject function. In this case the application can control the time stamp inject per packet using a (configurable) bit in the descriptor.

In total 10 bytes will be injected. The first two bytes are used as a 16 bit 1's compliment checksum. The next 8 bytes are the nanosecond precision time stamp stored in little endian format.

The position of an injected time stamp is in both cases determined by two other ini-settings, i.e. TimestampInjectDynamicOffset and TimestampInjectStaticOffset. The dynamic offset can be "Start Of Frame", "Start Of Layer 3", "Start Of Layer 4" or "End Of Frame". The static offset is a number which is added to the dynamic offset to get the actual position where the time stamp is injected.

When time stamp injection is used at the same time as L3/L4 checksum calculation, the position of the time stamp inject must be 2 bytes aligned with respect to start of Layer 3. Further, it is required that the 10 bytes where the time stamp will be injected are coded as all-zeros.

The command field is 1 bit wide with the following encoding:

  • 0 : No time stamp inject
  • 1 : Time stamp inject