Flow Matcher

Reference Documentation

product_line_custom
Intel® PAC
Napatech SmartNIC
category
Reference Information
Napatech Software Suite: Flow Matcher

Introduction

The flow matcher feature is designed for bi-directional flow matching. The feature is specifically designed for flow matching based on IP addresses, IP protocol field and L4 ports but the flexibility of the implementation allows flow matching to be performed on many other combinations of fields from the received packets.

The figure below illustrates the basic flow matcher principle.

Prerequisites: A filter using the Flow matcher is configured using NTPL. Flows to be matched are programmed into the Flow Matcher Table using the NT_FlowWrite() function in a Flow Stream. This is further described later in this section.

Incoming packets are decoded to provide information about the packets to the configured packet filter (e.g. port, layer 2 protocol, layer 3 protocol, tunneling, etc.). If the packet filter rules match a packet, the packet filter provides a set of rules for extraction of fields from the packet. The extracted fields are concatenated and a Key Id number from the NTPL filter configuration is appended. The resulting value is the packets key.

Then a look-up is done in the flow matcher table to see if any flow matcher table entry contains the packets key value. If the packet key is found in the flow matcher table, the compare will output a KeySet Id value associated with the matching key. This KeySet Id value is then compared to an expected KeySet Id value from the packet filter. In case of a match (aka a filter hit) the actions associated with the packet filter will be applied to the incoming packet.

flm_basic.png
Flow matcher principle

Configuration of packet filter and field extractor is done using the NTPL commands KeyType, KeyDef and Assign.

The flow matcher table is configured using a Flow Stream. The flow stream allows fast, dynamic create and remove of entries in the flow matcher table. More than 1 M flow entries can be changed per second. The flow matcher table can hold 100 M flow entries.

A part of the NTPL filter commands is to configure Key Id and KeySet Id. These values are then used during flow programming to establish a link between entries in the flow matcher table and the filter. Filters using different extraction rules shall therefore also use different Key Id. A single Key Id may be used for several KeySet Id values. This allows for selection of actions per flow.

Besides create (aka learn) and remove (aka unlearn) of flow entries, the flow stream is also used for reading flow learn status records and flow information records upon flow termination.

Flow status records are generated as asynchronous responses to flow programming operations. Flow status records contains information about the programming operation, i.e. whether the operation was sucessfully carried out or failed. See NT_FlowStatusRead() for further description of the 5 different status records.

If flows are programmed with the gfi-flag in the flow programming record set, the Flow matcher will gather packet statistics for the flow, i.e. number of packets, number of octets and TCP flags. When a flow is terminated, i.e. removed from the Flow Matcher Table, a flow information record with the statistics is generated. The application reads the record using NT_FlowRead().

Use cases

The features and functions of the flow matcher and its configuration will be described in the following sections through a number of use cases.

Monitoring IP flows in tap port configuration

Configuration of a simple monitor application for collection of IP flow traffic statistics is described below. In this use cases the Napatech adapter receives one direction of the monitored link on port 0 and the other direction on port 1.

The basic operation of this monitoring application is that packets from new flows are received by the application using a network stream. When a packet is received, the application programs the flow into the flow matcher so that subsequent packets from the same flow will be handled and counted by the flow matcher in HW. When the flow is unlearned, the flow matcher generates a flow information record for the application with packet and octet counters for the flow for the two flow directions.

flm_tap_config.png
TAP configuration

Using the configuration stream the application applies the desired NTPL in order to setup packet filter and field extractor. The NTPL example below configures the packet filter to match on IPv4 packets carrying either TCP or UDP. Further, the flow matcher is configured to use IPv4 addresses, layer 4 ports and IP protocol field as key.

KeyType[Name=kt] = {sw_32_32, sw_16_16}
KeyDef[Name=kd; KeyType=kt; IpProtocolField=Outer] = (Layer3Header[12]/32/32, Layer4Header[0]/16/16)
Assign[StreamId=0; Priority=2] = Port==0,1 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP
Assign[StreamId=Drop; Priority=1] = Port==0 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSA) == 4
Assign[StreamId=Drop; Priority=1] = Port==1 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSB, FieldAction=Swap) == 4

The KeyType command defines that two fields shall be extracted. The first field is a 2x32 = 64 bit field and the second field is a 2x16 = 32 bit field. The special feature of these sw_N_N fields is that the flow matcher can swap the two N bit subfields during field extraction in order to generate identical keys for upstream and downstream direction of a flow. This is further described later in this section.

The KeyDef command defines the location of the fields. The first field is extracted from the layer 3 header with a 12 byte offset. Since the filter will match IPv4 packets this correspond to extraction of source and destination IP addresses. The second field is extracted from the layer 4 header with a 0 byte offset. Since the filter will match TCP and UDP packets this correspond to extraction of source and destination port.

The KeyDef command also defines that the IP protocol field shall be taken from the outer IP protocol and used as part of the key. In this way the key is a 5-tuple consisting of src IP, dst IP, IP protocol, src port and dest port.

The first Assign command defines a filter that doesn't use the flow matcher (i.e. there are no Key expression in the filter). This filter will match IPv4 packets carrying either TCP or UDP from both port 0 and 1. Packets that matches this filter (and doesn't match any higher priority filter) will be send to the application in the network stream with Id 0.

The second Assign command defines a filter that uses the flow matcher. The Key expression enables the flow matcher and defines that statistics for matching packets shall be stored in counter set A in the flow information record. Like the first filter this filter will will match IPv4 packets carrying either TCP or UDP but only from port 0. Packets matching this filter will be dropped after update of statistic counters, i.e. StreamId=Drop. The "KeyId=1" of the Key-test is used as unique identifier for the KeyType and is used by the application when flows are programmed into the flow matcher. Also notice that this filter has higher priority than the first filter.

The third filter is identical to the second filter with three exceptions. This filter matches packets from port 1, statistics will be stored in counter set B and the field extractor is configured to do Swap of subfields when constructing the packet key. This ensures that packets on port 0 and packets on port 1 belonging to the same flow, will end up with the same packet key. This is illustrated in the figure below.

flm_tap_fieldswap.png
Field swap using FieldAction

The overall effect of the NTPL above is that packets belonging to the same flow can be matched by a single key in the flow matcher. Packets matched by the flow matcher will be counted and then dropped. Packets not being matched in the flow matcher will be send to the application for further processing. One type of processing could be to program the flow into the flow matcher in order to HW off-load subsequent packets from that flow.

The application must use the data structure defined for the Flow Stream to program flows into the flow matcher table. Using the packet in the above figure as an example, the fields in the NtFlow_s struct is to be programmed like:

NtFlow_t flow;
flow.id=42 // An ID used by the application to identify the flow.
// The ID will be returned in status and information records.
flow.keyData = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 0, 2, 0, 0, ....} // Fields in accordance with KeyDef
flow.keyId = 1 // As used in the NTPL
flow.keySetId = 4 // As used in the NTPL
flow.ipProtocolField = 6 // 6 for TCP, 17 for UDP
flow.op=1 // operation = learn flow
flow.gfi=1 // Generate information records with flow statistic
flow.tau=1 // Automatic unlearn TCP flows when connection terminates
flow.color=0 // Not used in this example
flow.overwrite=0 // Not used in this example
flow.streamId=0 // Not used in this example

When the data structure is filled, the application uses the flow stream function FlowWrite to program the flow into the flow matcher table.

When the flow later on is removed (aka unlearned) from the flow matcher table, the flow matcher will generate an information record containing flow statistics for the two directions of the flow. The application uses FlowRead to read the information record.

Flows can be unlearned in possible ways:

1) The application can unlearn the flow. This is using FlowWrite as described above. The only difference is that the op-field shall have the value zero to set the operation to Unlearn.

2) Flows may be unlearned based on timeout. This is enabled/configured using the FlowTimeOut setting in ntservice.ini. For flows programmed using gfi=1 the timeout is measured from the last packet received. For flows programmed using gfi=0 the timeout is measured from the time the flow was programmed.

3) TCP connections may automatically be unlearned by the flow matcher when it detects that the TCP connection is terminated. This feature is enabled when the flows learn record uses "tau=1" and disabled for "tau=0".

Flow specific actions

The flow matcher allows the application to select actions per flow. This is done by using multiple Assign commands where the filter expression only differs on the KeySetId value used in the KeyTest

Example:

KeyType[Name=kt] = {sw_32_32, sw_16_16}
KeyDef[Name=kd; KeyType=kt; IpProtocolField=Outer] = (Layer3Header[12]/32/32, Layer4Header[0]/16/16)
Assign[StreamId=0; Priority=2] = Port==0,1 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP

Assign[StreamId=Drop; Priority=1] = Port==0 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSA) == 4
Assign[StreamId=Drop; Priority=1] = Port==1 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSB, FieldAction=Swap) == 4

Assign[StreamId=2; Priority=1] = Port==0 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSA) == 5
Assign[StreamId=2; Priority=1] = Port==1 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSB, FieldAction=Swap) == 5

Assign[StreamId=3; Slice = Layer4Header[8]; Priority=1] = Port==0 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSA) == 6
Assign[StreamId=3; Slice = Layer4Header[8]; Priority=1] = Port==1 and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and Key(kd, KeyID=1, CounterSet=CSB, FieldAction=Swap) == 6

The above NTPL uses 3 different KetSetId values with the following actions:

KeySetId==4 : Drop matching packets

KeySetId==5 : Send matching packets to network stream 2

KeySetId==6 : Slice matching packets and send them to network stream 3

A flow programming like:

NtFlow_t flow;
flow.id=42
flow.keyData = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 0, 2, 0, 0, ....}
flow.keyId = 1
flow.keySetId = 4 // Apply the actions associated with KeySetId 4
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=0
flow.overwrite=0
flow.streamId=0

will result in a drop of all packets belonging to the flow.

A flow programming like:

NtFlow_t flow;
flow.id=42
flow.keyData = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 0, 2, 0, 0, ....}
flow.keyId = 1
flow.keySetId = 6 // Apply the actions associated with KeySetId 6
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=0
flow.overwrite=0
flow.streamId=0

will result in a slicing of all packets belonging to the flow before the packets are delivered to the application in the network stream with ID 3.

Flow specific stream overwrite

The Flow matcher allows for flow specific stream selection, i.e. the network stream selection can be programmed into the Flow matcher at the same time as the flow is programmed.

When using the stream overwrite functionality the range/group of valid stream IDs must be pre-allocated using the Assign command with the Flow matcher specific style "StreamId=Overwrite()".

The example below shows how to implement stream overwrite.

KeyType[Name=kt; StreamInfo=True] = {sw_32_32}
KeyDef[Name=kd; KeyType=kt; IpProtocolField=Outer] = (Layer3Header[12]/32/32)
Assign[StreamId=Overwrite(0..3)] = Port == 0 and Layer3Protocol == IPv4 and Key(kd, KeyID=1) == 4
Assign[StreamId=Overwrite(0..3)] = Port == 1 and Layer3Protocol == IPv4 and Key(kd, KeyID=1, FieldAction=Swap) == 4

The application can now program flows into the Flow matcher so that the flow packets will be delivered to 1 of 4 network streams, i.e. stream ID 0, 1, 2 or 3.

When programming flows from applications, the NtFlow_t fields "overwrite" and "streamId" is used for enabling the stream overwrite functionality and for selecting the streamId.

A flow programming like:

NtFlow_t flow;
flow.id=42
flow.keyData = {1, 2, 3, 4, 5, 6, 7, 8, 0, 0, ....}
flow.keyId = 1
flow.keySetId = 4
flow.ipProtocolField = 6 // TCP
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=0
flow.overwrite=1 // Enable stream overwrite
flow.streamId=1 // Select stream ID

will cause TCP packets between host-IP 1.2.3.4 and host-IP 4.5.6.7 to be delivered to the application using the network stream with id 1.

A flow programming like:

NtFlow_t flow;
flow.id=42
flow.keyData = {1, 2, 3, 4, 5, 6, 7, 8, 0, 0, ....}
flow.keyId = 1
flow.keySetId = 4
flow.ipProtocolField = 17 // UDP
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=0
flow.overwrite=1 // Enable stream overwrite
flow.streamId=3 // Select stream ID

will cause UDP packets between host-IP 1.2.3.4 and host-IP 4.5.6.7 to be delivered to the application using the network stream with id 3.

IP flows in span port configuration - key sorting

In span port configurations the up- and down-stream packets of a flow may be received on the same port on the Napatech adapter as illustrated in the figure below.

flm_span_config.png
SPAN port configuration

Since the packets from the two direction of a flow is received on the same port, the "FieldAction=swap" feature used in the previous examples are not applicable. Instead the flow matcher provides a key field sorting feature.

The sorting is based on the numerical value of the first two fields extracted from the incoming packet. If the numerical value of the first protocol field of a packet is greater than the numerical value of the second protocol field, the fields will be swapped before key look-up. If a swap of the first two keys is done and if the KeyType has 4 fields, a swap of field 3 and field 4 will also be done. The typical application is that field 1 and 2 are used for IP addresses while field 3 and 4 are layer 4 port numbers.

The automatic field sorting is enabled using the KeySort option in the KeyDef command as shown below.

keytype[name=kt] = {32, 32, 16, 16}
keydef[name=kd;keytype=kt;ipprotocolfield=outer;keysort=sorted] = (layer3header[12]/32, layer3header[16]/32, layer4header[0]/16,layer4header[2]/16)
assign[streamid=0;priority=1] = port==0 and layer3protocol==ipv4 and layer4protocol==tcp,udp
assign[streamid=drop;priority=0] = port==0 and layer3protocol==ipv4 and layer4protocol==tcp,udp and key(kd,KeyID=1) == 4

Consequently, when sorting is enabled packets with srcIP=1.2.3.4, dstIp=5.6.7.8, srcPort=1 and dstPort=2 and packets with srcIP=5.6.7.8, dstIp=1.2.3.4, srcPort=2 and dstPort=1 will generate the same packet key value. The application must perform the same sorting when programming flows, i.e. to match the flow, the application must program the flow using the structure values below:

NtFlow_t flow;
flow.id=42
flow.keyData = {1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 0, 2, 0, 0, ....} // IP addresses sorted and ports swapped accordingly
flow.keyId = 1
flow.keySetId = 4
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=0
flow.overwrite=0
flow.streamId=0

When sorting is used, counter set A will count packets where swap wasn't performed and counter set B will count packets where swap was performed.

VLAN, IPv4, IPv6 example

The example below configures the Flow matcher for matching on VLAN. The keys are constructed from VLAN ID, IP source/destination address, IP protocol field and TCP/UDP source/destination ports, i.e. a 6-tuple.

Packets not matched by the Flow matcher will be send to network stream 1 (IPv6) or network stream 2 (IPv4).

When the application programs flows into the Flow matcher, it can select between 3 different actions for the flow.

  • KeySetId==5 : Matching packets will be send to network stream 3 (IPv6) or network stream 4 (IPv4).
  • KeySetId==6 : Matching packets will be dropped, i.e. not send to the application.
  • KeySetId==7 : Matching packets will be forwarded on the other port, i.e. packets received on port 0 will be forwarded on port 1 and vice versa.

The KeyType commands used in this examples have ColorInfo=True. This means that the application can control the color of the flows during flow programming.

IPv6 configuration:

# Define the 6-tuple key, i.e. 5 explicit fields plus IP protocol field
KeyType[Name=ktIPv6; ColorInfo=True] = {16, sw_128_128, sw_16_16}
KeyDef[Name=kdIPv6; KeyType=ktIPv6; IpProtocolField=Outer] = ({0x0fff:FirstVLAN[2]/16}, Layer3Header[8]/128/128, Layer4Header[0]/16/16)

# Create filter for catching packets not matched by the Flow matcher
Assign[StreamId=1; Priority=1; Color=1] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 0,1

# Create filter using Flow matcher to send packets to network stream 3 (KeySetId==5)
Assign[StreamId=3; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 0 and key(kdIPv6, KeyID=1, CounterSet=csa)==5
Assign[StreamId=3; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 1 and key(kdIPv6, KeyID=1, CounterSet=csb, FieldAction=swap)==5

# Create filter using Flow matcher to drop packets (KeySetId==6)
Assign[StreamId=drop; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 0 and key(kdIPv6, KeyID=1, CounterSet=csa)==6
Assign[StreamId=drop; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 1 and key(kdIPv6, KeyID=1, CounterSet=csb, FieldAction=swap)==6

# Create filter using Flow matcher retransmit packets (KeySetId==7)
Assign[StreamId=drop; Priority=0; DestinationPort=1] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 0 and key(kdIPv6, KeyID=1, CounterSet=csa)==7
Assign[StreamId=drop; Priority=0; DestinationPort=0] = Encapsulation==vlan and Layer3Protocol==IPv6 and Layer4Protocol==TCP,UDP and port == 1 and key(kdIPv6, KeyID=1, CounterSet=csb, FieldAction=swap)==7

IPv4 configuration:

# Define the 6-tuple key, i.e. 5 explicit fields plus IP protocol field
KeyType[Name=ktIPv4; ColorInfo=True] = {16, sw_32_32, sw_16_16}
KeyDef[Name=kdIPv4; KeyType=ktIPv4; IpProtocolField=Outer] = ({0x0fff:FirstVLAN[2]/16}, Layer3Header[12]/32/32, Layer4Header[0]/16/16)

# Create filter for catching packets not matched by the Flow matcher
Assign[StreamId=2; Priority=1; Color=2] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 0,1

# Create filter using Flow matcher to send packets to network stream 4 (KeySetId==5)
Assign[StreamId=4; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 0 and key(kdIPv4, KeyID=2, CounterSet=csa)==5
Assign[StreamId=4; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 1 and key(kdIPv4, KeyID=2, CounterSet=csb, FieldAction=swap)==5

# Create filter using Flow matcher to drop packets (KeySetId==6)
Assign[StreamId=drop; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 0 and key(kdIPv4, KeyID=2, CounterSet=csa)==6
Assign[StreamId=drop; Priority=0] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 1 and key(kdIPv4, KeyID=2, CounterSet=csb, FieldAction=swap)==6

# Create filter using Flow matcher retransmit packets (KeySetId==7)
Assign[StreamId=drop; Priority=0; DestinationPort=1] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 0 and key(kdIPv4, KeyID=2, CounterSet=csa)==7
Assign[StreamId=drop; Priority=0; DestinationPort=0] = Encapsulation==vlan and Layer3Protocol==IPv4 and Layer4Protocol==TCP,UDP and port == 1 and key(kdIPv4, KeyID=2, CounterSet=csb, FieldAction=swap)==7

The flow programming

NtFlow_t flow;
flow.id=42
flow.keyData = {0, 42, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 0, 2, 0, 0, ....}
flow.keyId = 102
flow.keySetId = 5 // Select action, i.e. send to network stream 4
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=7 // Matching packets will get color 7
flow.overwrite=0
flow.streamId=0

will result in packets belonging to the IPv4-TCP flow with srcIP=1.2.3.4, dstIP=4.5.6.7, srcPort=1, dstPort=2 in VLAN 42 to be send to the application.

The flow programming

NtFlow_t flow;
flow.id=42
flow.keyData = {0, 42, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 0, 2, 0, 0, ....}
flow.keyId = 102
flow.keySetId = 7 // Select action, i.e. packet forwarding
flow.op=1
flow.gfi=1
flow.tau=1
flow.color=8 // Matching packets will get color 8
flow.overwrite=0
flow.streamId=0

will result in packets belonging to the same flow to be forwarded.