API: Handle Packets and Configure a Flow

Stateful Flow Management

Napatech SmartNIC
User Guide

Use this example to handle unknown packets and learn them.

Once a flow stream to the SmartNIC has been established, flow learn records can be send to the SmartNIC via the NT_FlowWrite function. Flow learn records are implemented as the c-style structure NtFlow_t. The snippet below shows how a flow learn record is filled from a received packet from RX stream ID 1.

The flow learn record contains all relevant information for the flow manager, which includes IPv4 TCP data, and the Key ID that ties the flow learn record to the NTPL Assign command. It is important to note the gfi field is set to 1; this will cause flow info records to be generated when the flow is unlearned. Flow info records are discussed in following sections.

uint64_t idCounter = 0;
uint32_t streamId = 1;

NtNetStreamRx_t hNetRx;
NtNetBuf_t hNetBuffer;

// While not included here, it is needed to open a stream with
// StreamId=1 for hNetRx before the while loop.
while( /* Check application should continue */ ) {
    // Get package from rx stream.
    status = NT_NetRxGetNextPacket(hNetRx, &hNetBuffer, 100);
    if(status == NT_STATUS_TIMEOUT || status == NT_STATUS_TRYAGAIN) continue;
    if(status != NT_SUCCESS) { /* Handle error */ }

    // For this example the descriptor DYN3 is used, which is set up via NTPL.
    NtDyn4Descr_t* dyn4 = _NT_NET_GET_PKT_DESCR_PTR_DYN4(hNetBuffer);
    uint8_t* packet = reinterpret_cast<uint8_t*>(dyn4) + dyn4->descrLength;

    // In this example, the ID is a simple incremental value;
    // however, any value can be used, including the raw value of pointers.
    NtFlow_t flow;
    std::memset(&flow, 0x0, sizeof(NtFlow_t));
    flow.id = idCounter++;    // User defined ID
    flow.color = 0;           // Flow color
    flow.ipProtocolField = 6; // IP protocol number of next header (6: TCP)
    flow.keyId = 1;           // Key ID as used in the NTPL Key Test
    flow.keySetId = 4;        // Ket Set ID as used in the NTPL filter
    flow.op = 1;              // Flow programming operation
    flow.gfi = 1;             // Generate flow info record
    flow.tau = 1;             // TCP auto unlearn

    // The NTPL filters in this snippet set up an alternative offset0,
    // such that it points directly to the IP source address.
    std::memcpy(flow.keyData,      packet + dyn4->offset0,     4); // IPv4 src
    std::memcpy(flow.keyData + 4,  packet + dyn4->offset0 + 4, 4); // IPv4 dst
    std::memcpy(flow.keyData + 8,  packet + dyn4->offset1,     2); // TCP port src
    std::memcpy(flow.keyData + 10, packet + dyn4->offset1 + 2, 2); // TCP port dst

    // Program the flow into the adapter.
    status = NT_FlowWrite(flowStream, &flow, -1);
    if(status != NT_SUCCESS) { /* Handle error */ }