Data Filter

SmartNIC Filtering with Link-Capture™ Software

Platform
Napatech SmartNIC
Content Type
User Guide
Capture Software Version
Link™ Capture Software 12.11

Received frames can be filtered matching specific values at user-defined fields of a frame.

Defining data filters based on configurable fields

The following NTPL example configures a filter to deliver frames with one MPLS label to the host. It is done by comparing the bottom-of-stack (BoS) bit field in the first MPLS header of a frame.
Assign[StreamId=1] = Encapsulation==MPLS AND \\
Data[ProtOffset=FirstMPLS[0];DataType=ByteStr4;DataMask=[8:8]]==1
Frames are delivered to stream 1 if the BoS bit of the first MPLS header is 1.
Three elements are used to configure a user-defined field as follows.
  • ProtOffset=FirstMPLS[0]: The starting byte which is specified using a dynamic offset and a static offset where a dynamic offset is based on a predefined protocol layer, and a static offset is relative to the dynamic offset. In this example, FirstMPLS is the dynamic offset and [0] is the static offset. The starting byte is byte 0 of the first MPLS header in this example.
    Note: Supported static offset values are -1024 to 1023.
  • DataType=ByteStr4: The length of the field which is specified using DataType with ByteStr1 (1 byte), ByteStr2 (2 bytes) or ByteStr4 (4 bytes). A 4-byte field is specified in this example. The MAC (6 bytes), IPv4 (4 bytes) and IPv6 (16 bytes) address types are also supported.
  • DataMask=[8:8]: A bit mask using the first bit and the last bit. [8:8] indicates bit 8. For example, DataMask=[15:0] selects bit 15 to 0.
    Note: DataMask is represented in network byte order (big-endian).

Extractors and comparators

The SmartNIC has limited data filter resources. When utilizing data filters, data extracted from a frame is stored in the extractors of the SmartNIC. Each extractor is 4 bytes, and the SmartNIC contains 4 extractors in total. This implies that a maximum of 16-byte data can be defined for extraction from a frame. In the following NTPL example, the IPv4Addr data type is 4 bytes, consuming one extractor.
Define isIPv4 = Macro("Layer3Protocol==IPv4")
Define IPv4_Src = Macro("Data[ProtOffset=Layer3Header[12]; DataType=IPv4Addr]")

Assign[StreamID=0]= isIPv4 and IPv4_Src == [172.16.129.85]
The following NTPL example defines the IPv6Addr data type, which occupies 16 bytes. This filter requires 4 extractors.
Define isIPv6 = Macro("Layer3Protocol==IPv6")
Define IPv6_Src = Macro("Data[ProtOffset=InnerLayer3Header[24]; DataType=IPv6Addr]") 
Assign[StreamID=0]= isIPv6 and IPv6_Src == [2405:201:22:711c:0000:0000:c0a8:1d01]
If you try to apply the second filter after the first filter is applied, an error is generated as follows.
>>> Parsing expression "Assign[StreamID=0]=Data[ProtOffset=InnerLayer3Header[24];DataType=IPv6Addr] == [2405:201:22:711c:0000:0000:c0a8:1d01]" failed.
>>> Error: 0x200020E2
>>> Out of extractors
>>>
>>>
It is because not enough extractors are available in the SmartNIC. The first filter for the IPv4 address must be deleted to be able to apply the second filter. You can apply the following NTPL expression before the second filter to delete previously applied filters.
Delete=All
After applying the second data filter for the IPv6 address, it is not possible to define additional data filters as all 4 extractors are used.
The values to be compared are stored in the comparators of the SmartNIC. Each comparator is 4 bytes, and 32 comparators are available. The following NTPL example involves comparing two IPv4 addresses, which consumes 2 comparators.
Define isIPv4 = Macro("Layer3Protocol==IPv4")
Define IPv4_Src = Macro("Data[ProtOffset=Layer3Header[12]; DataType=IPv4Addr]")

Assign[StreamID=0]= isIPv4 and IPv4_Src == [172.16.129.85]
Assign[StreamID=0]= isIPv4 and IPv4_Src == [172.16.129.86]
This allows applying 30 additional IPv4 addresses.

The usage of filter resources can be checked using the FilterInfo command. See Filter resource.

Filtering on MPLS labels

The following NTPL example configures the SmartNIC to filter on MPLS labels.
// Define macros for the BOS bit field of MPLS headers.
Define MPLS0_Stack = Macro("Data[ProtOffset=FirstMPLS[0];DataType=ByteStr4;DataMask=[8:8]]")
Define MPLS1_Stack = Macro("Data[ProtOffset=FirstMPLS[4];DataType=ByteStr4;DataMask=[8:8]]")
Define MPLS2_Stack = Macro("Data[ProtOffset=FirstMPLS[8];DataType=ByteStr4;DataMask=[8:8]]")

// Stream 1: Frames with a single label.
Assign[streamid=1; priority=1]= (Encapsulation==MPLS) AND (MPLS0_Stack==1)

// Stream 2: Frames with two labels.
Assign[streamid=2; priority=2]= (Encapsulation==MPLS) AND (MPLS1_Stack==1)

// Stream 3: Frames with three labels. 
Assign[streamid=3; priority=3]= (Encapsulation==MPLS) AND ((MPLS2_Stack==1)

// Stream 4: Frames with more than three MPLS labels.
Assign[streamid=4; priority=4] = (Encapsulation==MPLS)

// Capture the rest frames.
Assign[streamid=0;priority=60] = all
Macros are used to simplify the filter expressions.
  • MPLS0_Stack: The BoS bit field of the first MPLS header.
  • MPLS1_Stack: The BoS bit field of the second MPLS header.
  • MPLS2_Stack: The BoS bit field of the third MPLS header.
This example configures the SmartNIC to deliver frames with one MPLS label to stream 1, frames with two MPLS labels to stream 2, frames with three MPLS labels to stream 3 and frames with more than three MPLS labels to stream 4.

Filtering on VLAN IDs

The following NTPL example configures the SmartNIC to filter on VLAN IDs.
// Macros for VLAN IDs.
Define VID0 = Macro("Data[ProtOffset=FirstVLAN[2];DataType=ByteStr2;DataMask=[11:0]]")
Define VID1 = Macro("Data[ProtOffset=FirstVLAN[6];DataType=ByteStr2;DataMask=[11:0]]")
Define VID2 = Macro("Data[ProtOffset=FirstVLAN[10];DataType=ByteStr2;DataMask=[11:0]]")

// Stream 5: Frames with the first VLAN ID 10,
// the second VLAN ID 11 and the third VLAN ID 12.
Assign[streamid=5; priority=4] = (Encapsulation==VLAN) AND (VID0==10) AND \\
(VID1==11) AND (VID2==12))

// Stream 6: All the rest VLAN frames. 
Assign[streamid=6; priority=10] = (Encapsulation==VLAN)
Frames with the first VLAN ID 10, the second VLAN ID 11 and the third VLAN ID 12 are delivered to stream 5.

Detecting RTP traffic for VoIP analysis

Identifying RTP traffic using UDP port numbers is not possible as UDP port numbers are dynamically assigned for RTP sessions. RTP frames can be identified by checking fixed known values of specific header fields as shown in the following NTPL example.

// Define filters for UDP and TCP traffic.
Define isUDP = Filter(Layer4Protocol==UDP)
Define isTCP = Filter(Layer4Protocol==TCP)

// Define macros for layer 4 source and destination port fields.
Define SrcPort = Macro("Data[ProtoOffset=Layer4Header[0];DataType=ByteStr4];DataMask=[15:0]")
Define DstPort = Macro("Data[ProtoOffset=Layer4Header[0];DataType=ByteStr4];DataMask=[31:16]")

// Macros for the RTP version field and the RTP payload type field.
Define RtpVer = Macro("Data[ProtoOffset=Layer4Payload[0];DataType=ByteStr1;DataMask=[7:6]]")
Define RtpPayloadType = Macro("Data[ProtoOffset=Layer4Payload[1];DataType=ByteStr1;DataMask=[6:0]]")

// Macro for the RTP frame length.
Define RtpLength = Macro("Length[Begin=Layer4Payload]")

// Distribute traffic based on UDP sessions
Hashmode = Hash5TupleSorted

// Deliver SIP traffic to stream 0.
Assign[StreamId = 0; Priority=0] = (SrcPort==5060, 5061 OR DstPort==5060, 5061) AND (isUDP OR isTCP)

// Distribute RTP traffic to streams 1 to 8 using Hash5TupleSorted.
Assign[StreamId=(1..8); Priority=1] = isUDP AND (SrcPort > 1023 OR DstPort > 1023) AND (RtpVer==2) AND \\
( RtpPayloadType==(0..23) OR RtpPayloadType==(96..127) ) AND (RtpLength >= 16) 

// Capture the rest frames.
Assign[StreamId = 9; Priority = 10] = All
The following rules are applied to identify RTP frames in this example.
  • Only UDP frames.
  • Source and destination port numbers of UDP must be higher than 1023.
  • The RTP version must be 2.
  • The RTP payload type must be within the range: 0 to 23, 96 to 127 (defined in RFC 3550).
  • The UDP payload must be greater than or equal to 16 bytes (a minimum length of the RTP header 12 bytes + FCS 4 bytes).
Note: SrcPort and DstPort are defined using one 4-byte field with bit masks, which consumes one extractor of filter resources.
Define SrcPort = Macro("Data[ProtoOffset=Layer4Header[0];DataType=ByteStr4];DataMask=[15:0]")
Define DstPort = Macro("Data[ProtoOffset=Layer4Header[0];DataType=ByteStr4];DataMask=[31:16]")
It is possible to define SrcPort and DstPort using two separate 2-byte fields as shown in the following example.
Define SrcPort = Macro("Data[ProtoOffset=Layer4Header[0];DataType=ByteStr2]")
Define DstPort = Macro("Data[ProtoOffset=Layer4Header[2];DataType=ByteStr2]")
This results in consuming two extractors of filter resources. As filter resources in the SmartNIC are limited, the example using one 4-byte field with bit masks is recommended.

Data filter on IPv4 addresses

This example shows filtering on IP addresses.
// Define macros for source and destination IPv4 addresses.
Define IPv4_Src = Macro("Data[ProtOffset=Layer3Header[12]; DataType=IPv4Addr]")
Define IPv4_Dst = Macro("Data[ProtOffset=Layer3Header[16]; DataType=IPv4Addr]")

// Define a filter for IPv4.
Define isIPv4 = Macro("Layer3Protocol==IPv4")

// Define a macro for gateway IPv4 subnet.
Define Gateway_IPv4 = Macro("{[ff.ff.00.00]:[201.100.0.0]}")

Assign[StreamId=7] = isIPv4 AND (IPv4_Src==Gateway_IPv4 OR IPv4_Dst==Gateway_IPv4)
Note: The data filter can be used for filtering frames containing a group of IP addresses, but only 32 IPv4 addresses or 8 IPv6 addresses can be configured as 32 comparators are available (each comparator is 32 bits). Use key match if a large list of values needs to be configured. See Key Match for more information on key match.