Assign Command

Reference Documentation

Platform
Intel® PAC
Napatech SmartNIC
Content Type
Reference Information
Capture Software Version
Link™ Capture Software 12.10
Napatech Software Suite: Assign Command

This section specifies the syntax and semantics for the assign command.

Supported Options Per Feature Set

Supported Feature Sets
N-ANL4 N-ANL5
N-ANL6
N-ANL7
N-ANL8
N-ANL9
N-ANL10 N-ANL11
X X X X
Options Priority X X X X
StreamId X X X X
Color X X X X
ColorMask   X X X
Slice   X X X
Hash   X X X
Descriptor   X X X
Align X X X X
TxIgnore X1 X1 X1 X1
TxNow X1 X1 X1 X1
CrcOverride X1 X1 X1 X1
TxPort X1 X1 X1 X1
DestinationPort     X X
TxMetaData     X X
CorrelationKey       X

Notes

  1. These options only set their respective values in the captured packet descriptor. This may in turn be used to affect inline transmission configured by Setup. For example, the Assign TxPort option can be used in conjunction with the Setup TxPortPos option to dynamically control the transmit port.

The syntax for creating a filter based packet handling rule is shown below.

<AssignAction>       ::= 'Assign' { '[' <AssignOptionList> ']' } '=' <FilterExpressionSpec>
<AssignOptionList>   ::= <AssignOption> { ';' <AssignOption> }
<AssignOption>       ::= ( 'Priority' '=' <Priority>) |
                         ( 'StreamId' '=' ( <StreamIdSpec> | 'Key' | <OverwriteSpec> ) |
                         ( 'Action' '=' <Identifier> ) |
                         ( 'Color' '=' <32-bit value> ) |
                         ( 'ColorMask' '=' <32-bit value> ) |
                         ( 'Slice' '=' <SliceRecipe> ) |
                         ( 'SliceReTx' '=' <SliceRecipe> ) |
                         ( 'Hash' '=' <HashRecipe> ) |
                         ( 'Descriptor' '=' <DescriptorRecipe> ) |
                         ( 'CorrelationKey' [ '=' <CorrelationKeyRecipe> ] ) |
                         ( 'Mask' [ '=' <MaskRecipe> ] ) |
                         ( 'HeaderStripper' [ '=' <HeaderStripperRecipe> ] ) |
                         ( 'Align' '=' ('Packed' | 'Byte8' ) ) |
                         ( 'TxIgnore' '=' <TrueFalseValue> ) |
                         ( 'TxNow' '=' <TrueFalseValue> ) |
                         ( 'CrcOverride' '=' <TrueFalseValue> ) |
                         ( 'TxPort' '=' <PortNumberSpec> ) |
                         ( 'DestinationPort' '=' <PortNumberSpec> ) |
                         ( 'Tag' '=' <Identifier> ) |
                         ( 'TxMetaData' '=' 'TimeStamp' )
<OverwriteSpec>      ::= ( 'Overwrite' ( <StreamIdRangeSpec> | '(' <StreamIdSetSpec> ')' ) )

Assigning Filters

Each assign command defines a new filter based rule. Each rule affects how a received packet is treated with respect to these 5 functions: distribution to streams, coloring, slicing, hashing and packet descriptor. You don't need to specify all parameters in every assign expression. For each function, the filter with the highest priority containing a recipe for that function defines how the packet is treated in that function. An example should illustrate this. Suppose two filters are defined:

1: Assign[StreamId = 1; Priority = 20; Slice = Layer4Header[008]] = Length >= 300
2: Assign[StreamId = 2; Priority = 10;] = Length >= 1000

Filter 1 matches all frames with length greater than or equal to 300 bytes. Filter 2 matches all frames with length greater than or equal to 1000 bytes. Suppose a frame with a length of 1000 bytes is received. Both filters will match with filter 2 having the highest priority (see definition of priorities below). Because filter 2 has the highest priority and it defines a 'StreamId' recipe, the frame will be sent to stream 2. Filter 2 does not define a 'Slice' recipe, however filter 1 does and because it is the next highest priority filter that also matches the frame, the frame is sliced according to filter 1's 'Slice' recipe.

If no filter introduces a new recipe for the function, the default recipe is used.

Default recipes are:

  • StreamId: 'DROP' (Packet is discarded)
  • Color: 0 (Zero)
  • Slice: No slicing
  • SliceReTx: No slicing
  • Hash: RoundRobin
  • Descriptor: As specified in .ini file.

Filter expressions can be given priority with the 'Priority' parameter. 0 is the highest priority, and 62 is the lowest priority. If two expressions have the same priority, the one entered last wins. Default priority is 0.

The 'StreamId' parameter will assign the specified traffic to the specified stream(s). This is done using one host buffer per stream specified. See the Setup command for details on how to set up host buffer properties for a given stream. If multiple streams are specified, the packets will be distributed according to the effective hash method. If the keyword "Key" is used, the destination stream will be taken from the key matcher (see KeyType Command and KeyList Command) instead. An error is thrown if "Key" is used and there are no Key Tests in the right-hand-side of the Assign statement. As an alternative to "Key" the keyword "Overwrite" can be used. "Key" and "Overwrite" serves the same purpose, with the difference that "Overwrite" also assigns StreamIds. Overwrite example. 'Action' can be used instead of 'StreamId' parameter, see Action Command for more info.

Color can be handled in two different ways: The prioritized color or the color mask. Normally you would not mix the two approaches. The color will both be visible in the descriptors that contain a color field and in the color statistics (the color statistics will, however, only be based on the lower 6 bits of the color field).

'Color' specifies the prioritized color that is assigned to packets being captured by this filter. If several filters match a packet, only the highest priority filter with a prioritized color will set the prioritized color in the packet descriptor. To retrieve the color for a specific packet use the NT_NET_GET_PKT_COLOR macro or access the field directly in case dynamic descriptors are used.

'ColorMask' specifies an un-prioritized color bitmask that will be OR'ed to the final color of a captured packet when it matches the given filter. This way several matching filters can contribute to the final color of a packet. The final color of a packet will be the bitwise OR of the prioritized color and the un-prioritized color masks. The 'Color' and 'ColorMask' options are mutually exclusive within the same Assign command.

Note: Although the color and color mask values given in an assign command are specified as a 32-bit number only the bits supported by the descriptor eventually selected for a packet will contribute to the color. I.e. it would not make sense to use Color/ColorMask values greater than 63 if the descriptor only has a 6-bit color field.

Although using the 'Hash' = <HashRecipe> combined with a filter expression is the "modern" way to specify hashing, the old way using the HashMode command can still be used. The hash mode command will translate into a number of assign expressions only carrying information about hashing. Use the new method when more flexibility is needed.

Use the 'Slice' option if you want to store only a part of the packet.

The 'DestinationPort' option activates the local retransmit feature where packets can be retransmitted on the specified ports locally on the adapter, without involving the host application(s). When using this option the transmission port must be on the same adapter, and the filter specified in the "<FilterExpressionSpec>" must be restricted to only apply to that adapter using a port expression. When using the 'TxMetaData = TimeStamp' option in connection with 'DestinationPort', the receiving timestamp is appended to the retransmitted packet along with a new FCS, before re-transmission. The appended timestamp is in native UNIX nanosecond format. When using this option, the packet expansion will cause oversubscription on the TX path, when receiving packets at line rate, i.e. packet drops can occur. If this is unacceptable, the timestamp can be appended in an inline scenario, where the hostbuffer can absorb the over subscription pressure (see Setup Command)

Note that the 'StreamId' and the 'DestinationPort' option do not share the 'Priority' option. As an example, this means that even if a packet hits a high priority filter using 'StreamId', the same packet can also hit a low priority using 'DestinationPort', resulting in the packet being both retransmitted and received on an RX stream.

Use the 'Tag' option to associate a name with the command. Multiple commands can be associated with the same tag. Tags makes it convenient to cancel/delete only a subset of configured filters (see the Delete command).

Note: An Assign command is cancelled by issuing a Delete command specifying the Ntpl ID or Tag in question.

To modify a filter without loss of data while the network adapter is receiving data, do the following:

  • Define a new filter with the required modifications.
  • Delete the old filter. If you delete the old filter first, this results in the release of the associated hostbuffer(s) which again may lead to loss of packets.

Note: It is only possible to use this method when the necessary extra filter resources are available.

Descriptor Options

If one of the descriptor options are present, a recipe for the descriptor function is created. The default values for the recipe is as follows:

  • Descriptor type: as specified in the ini file
  • TxIgnore: False
  • TxNow: False
  • CrcOverride: False
  • TxPort: 0 (Zero)
  • Align: 'Packed' (Packets are stored back-to-back).

The 'Descriptor' option is used to select which packet descriptor to add to the packets matching the specific filter. Main use is to select dynamic packet descriptor (see below). The selected descriptor format must be compatible with the time stamp format selected in TimestampFormat setting in ntservice.ini. This means that selecting PCAP timestamp formats prohibits the selection of NT/EXT/DYN descriptors.

The 'TxIgnore', 'TxNow', 'CrcOverride' and 'TxPort' options make the hardware fill in the TX fields in the packet descriptor when the frames are received (provided the descriptor contains the relevant fields). These fields can be used to control transmission in inline or capture-replay scenarios. How the fields affect transmission depends on the configured transmission mode.

  • 'TxIgnore' specifies the setting of the txIgnore bit in the standard packet descriptor of the received frames. When TxIgnore is set to TRUE, the txIgnore bit in the standard packet descriptor is set to 1. When TxIgnore is set to FALSE, the txIgnore bit is set to 0.
  • 'TxNow' specifies the setting of the txNow bit in the standard packet descriptor of the received frames. When TxNow is set to TRUE, the txNow bit in the standard packet descriptor is set to 1. When TxNow is set to FALSE, the txNow bit is set to 0.
  • 'CrcOverride' specifies the setting of the txCrcOverride bit in the standard packet descriptor of the received frames. When CrcOverride is set to TRUE, the txCrcOverride bit in the standard packet descriptor is set to 1. When CrcOverride is set to FALSE, the txCrcOverride bit is set to 0.
  • 'TxPort' specifies the setting of the txPort bits in the standard packet descriptor of the received frames. The default value is 0. 'TxPort' can be a value, a set of values or a range of values. When more than one value is specified, the number of stream ids must be a multiple of the number of Tx ports specified. The first stream will get the first 'TxPort', the second stream will get the second 'TxPort' and so on. When the last 'TxPort' value is reached, the next stream will get the first Tx port.
  • If 'Align' is set to 'Packed', packets are stored back-to-back in the buffer without padding in between. This is the default. If you slice packets, you should use 'Packed'. If you run 'Byte8' alignment, there is no way you can tell if zero bytes in the end of the packet are padding or if they come from the original packet.

Setting Up Multi-CPU distribution

When setting up multi-CPU buffer distribution, you must consider the following:

  • To which streams should the traffic be sent?
  • What is algorithm used for distribution: "Round Robin", random or hash value based?
  • If hash value based - which fields in the packet should be used for hash value generation?

Specifying Destination Streams

The streams that the traffic should be distributed to are specified by giving a range or list of streams as 'StreamId' argument in one or more 'Assign' commands:

Assign[StreamId=7] = All
Assign[StreamId=(0..6)] = Layer4Protocol == UDP, TCP

These commands say that all trafic should be sent to stream 7 by default, but all UDP and TCP traffic should be distributed between streams 0, 1, 2, 3, 4, 5 and 6. This example does not use explicit priorities, but relies on the UDP/TCP filter being last, and therefore takes precedence over the all filter when hit.

Specifying Algorithm

By default the packets will be distributed to the streams in a round robin fashion. This means that the packets will be sent to the streams in turn. When the last stream has received a packet, the next one to receive will be the first.

If you want to be sure that the packets with some of the same properties are sent to the same stream, you will use the hash value based algorithm. One example could be that you just want to be sure that packets with the same destination IP address are sent to the same stream. You can then specify the hash recipe like this:

Assign[ Hash = HashWord0_3=Layer3Header[12]/32 ] = Layer3Protocol == IPv4

This essentially says: "For all IPv4 packets, form a hash key using the 32 bits located at position 12 in the layer 3 header (which will be an IPv4 header)". Refer to Hash Recipe for more options.

This way of specifying the hash key directly in an assign command is used, when you want to define a key yourself. You can use the HashMode command if you can use the predefined keys:

HashMode = Hash5Tuple

Together with the assign commands from the previous subsection this will define a setup where all UDP and TCP frames are divided between streams 0 to 6 based on 5-tuple unsorted hash key values, and where stream 7 must receive all other frames, for instance ARP and ICMP frames.

Examples Using Hashing

Example Using both Filter Logic and Hash Keys.

This section describes an example of a flow definition using a combination of filter logic results and hash key values.
The example illustrates how to define a flow where:

  • All UDP/VoIP frames must be divided between streams 0, 1, 2 and 3 based on hash key values.
  • All HTTP frames must be divided between streams 4 and 5 based on hash key values.
  • Stream 6 must receive all ARP frames.

This setup is done using the following commands on a stream. The possibility to define named filters is used to enhance readability:

Define IsUdpVoip = Filter(Data[DynOffset=DynOffUDPFrame;DataType=ByteStr2] == (16000..16500))
Define SrcPortIsHttp = Filter(Data[DynOffset=DynOffTCPFrame;Offset=0;DataType=ByteStr2] == 80)
Define DestPortIsHttp = Filter(Data[DynOffset=DynOffTCPFrame;Offset=2;DataType=ByteStr2] == 80)
Define IsHttp = Filter(SrcPortIsHttp OR DestPortIsHttp)
Define IsArp = Filter(Data[DynOffset=DynOffEtherTypeLen; DataType=ByteStr2] == 0x0806)

HashMode = Hash5TupleSorted
Assign[StreamId = (0..3)] = IsUdpVoip
Assign[StreamId = 4,5] = IsHttp
Assign[StreamId = 6] = IsArp

Balance Tunneled Traffic

This section describes an example where traffic to/from a client IP inside a tunnel is balanced between streams, i.e. the traffic from/to one client go to one host buffer and to/from a second client to another host buffer based on inner tunnel hash key.

Using Port Filter

Assume a client has an IP address 192.168.0.1 and it connects to remote IP addresses Y and Z. All the traffic from/to IP address 192.168.0.1 should end up in the same stream regardless of the destination IP address Y and Z. Also assume that all uplink traffic is on port 0, all downlink traffic is on port 1 and all tunneled traffic is IPv4. The idea is to generate a hash value from a key that only contains the client IP address. In uplink traffic coming from port 0 the address will be the source address and in downlink traffic from port 1 the address will be the destination. This can be expressed in the following commands:

Define HashUp = Hash(HashWord0_3=InnerLayer3Header[12]/32)
Define HashDown = Hash(HashWord0_3=InnerLayer3Header[16]/32)
Define FilterUp = Filter(Port==0)
Define FilterDown = Filter(Port==1)
Assign[Hash = HashUp] = FilterUp
Assign[Hash = HashDown] = FilterDown

Using IP Filter

Consider the case where similar functionality is wanted, but instead of having one port for uplink and one for downlink, the connection is a SPAN/mirror port. In this case the IP addresses of the possible gateways in and out of our network (SGSN and GGSN) must be known in order to be able to figure out if a packet is uplink or downlink. Uplink trafic has SGSN as source address OR GGSN as destination address. Downlink traffic has SGSN as destination address OR GGSN as source address. The up/down filters can in this case be defined like this:

DefineMacro("SGSN", "3")
DefineMacro("GGSN", "4")
IPMatchList[KeySet=SGSN] = IPv4Addr == [10.10.10.1]
IPMatchList[KeySet=GGSN] = IPv4Addr == [172.20.20.1]
Define FilterUp = Filter(KeyMatch(Layer3Header[12]/32)==SGSN OR KeyMatch(Layer3Header[16]/32)==GGSN)
Define FilterDown = Filter(KeyMatch(Layer3Header[12]/32)==GGSN OR KeyMatch(Layer3Header[16]/32)==SGSN)
Assign[Hash = HashUp] = FilterUp
Assign[Hash = HashDown] = FilterDown

This is an example where the KeySet attribute can be used to match against different sets of IP addresses.

Examples With Dynamic Descriptors

Using Hash Recipes And Specific Descriptors.

This section describes an example of a flow definition using the 'Hash' option. The 'Descriptor' option is used to add 'DYN2' descriptors to packets matching these filters. The 'HashUp' and 'HashDown' identifiers are defined in the example above.

Assign[StreamId=(0..31), Hash = HashUp, Descriptor = DYN2] = port==0
Assign[StreamId=(0..31), Hash = HashDown, Descriptor = DYN2] = port==1

Dynamic Descriptors with User-Programmed Offsets

This section illustrates the use of dynamic descriptors with user-programmable offsets.

The first example uses a dynamic descriptor 1 where the offsets are set to point to:
0: 4 bytes into the outermost ip header
1: The start of the outermost layer 4 header
2: 6 bytes into the outermost layer 4 payload

Assign[Descriptor=DYN1,Offset0=Layer3Header[4],Offset1=Layer4Header[0],Offset2=Layer4Payload[6]] = port==0

The next example uses a dynamic descriptor 2 where the offsets are set to point to:
0: 6 bytes into the outermost layer 2 header
1: The tunneled destination ip address field
2: The start of the tunneled layer 4 header

Assign[Descriptor=DYN2,Offset0=Layer2Header[6],Offset1=InnerDestinationIp[0],Offset2=InnerLayer4Header[0]] = port==0

Assign Filter Using Slicing

This section describes some examples of Assign commands with slicing.

Conditional Slicing at Fixed Offset

This section describes an example of a filter for conditional slicing at a fixed offset.

The example illustrates how to set up conditional slicing of all UDP frames to a size of 64 bytes. When dynamic slicing is set up in this way, the size of a UDP frame delivered to the host memory is always 64 bytes or less, including any protocol headers (such as VLAN and MPLS tags) that might be present.

The filter NTPL example is shown below.

Assign[StreamId = 1; Slice=StartOfFrame[64]] = Layer4Protocol == UDP

The parameter, StartOfFrame[64], specifies that frames are sliced to 64 bytes. Layer4Protocol == UDP specifies that this only applies to UDP frames. After slicing the packets are sent to stream 1.

Conditional Slicing at Dynamic Offset

This section describes an example of a filter for conditional slicing at a dynamic offset.

The example illustrates how to set up conditional dynamic slicing of all TCP frames to a size of 64 bytes plus the size of any layer 2, 3 and 4 protocol headers. That is, a TCP frame with a payload of 64 bytes or more will be sliced so that the frame will be delivered to the host with a TCP payload of 64 bytes.

The filter NTPL example is shown below.

Assign[StreamId = 1; Slice=Layer4Payload[64]] = Layer4Protocol == TCP

The parameter Layer4Payload[64], specify that frames are sliced to 64 bytes into the layer 4 payload. Layer4Protocol == TCP specifies that the filter only applies to TCP frames. After slicing the packets are sent to stream 1.

Conditional Dynamic Slicing using Slicing Priority

This section describes an example of three filters for conditional dynamic slicing using different conditional dynamic slicing priorities to prioritize between overlapping slicing definitions.

The examples illustrate how to set up conditional dynamic slicing of TCP frames to a size of 150 bytes, other IP frames to a size of 128 bytes and all remaining frames to a size of 64 bytes.

The filter NTPL example is shown below.

Assign[Priority = 62; Slice=StartOfFrame[64]] = all
Assign[Priority = 2;Slice=StartOfFrame[128]] = Layer3Protocol == IP
Assign[Priority = 0; Slice=StartOfFrame[150]] = Layer4Protocol == TCP
Assign[StreamId = 1] = all

The first filter, Assign[Priority = 62; Slice=StartOfFrame[64]] = all, defines the default slicing of packets to 64 bytes. The priority of this filter is 62 (the lowest priority).

The two subsequent filters defines how IP packets and TCP packets should be sliced. As the IP filter has a priority of 2, it overrules the All filter for all packets where the layer 3 protocol is either IPv4 or IPv6. For packets where layer 4 protocol is TCP, the filter with the highest priority (0) overrules the two other filters and causes the packet to be sliced to a max length of 150 bytes.
The last 'Assign' command specifies that all packets should be sent to stream 1 regardless of how the slicing is done.

Note: The order in which the first three 'Assign' commands are issued has no influence on the resulting dynamic slicing, as the explicit priorities specify how to handle the overlapping filters.

Conditional Slicing on local retransmit

It is possible to slice packets that are to be retransmitted using the SliceReTx assign option. The syntax is the same as the regular Slice option. When using SliceReTx the DestinationPort option must also be used. The two slicers work completely independent from each other.

In the NTPL below, all packets received on port 0 are sliced to 80 bytes and retransmitted on port 1. IPv4 packets received on port 1 are sliced to 80 bytes and retransmitted on port 0, but also delivered to host with StreamId 0 with the full length. IPv6 packets received on port 1 are sliced to 80 bytes and retransmitted on port 0, but also delivered to host with StreamId 0 having the packets sliced to 64 bytes.

Assign[DestinationPort=1; SliceReTx=StartOfFrame[80]] = Port == 0
Assign[StreamId=0; DestinationPort=0; SliceReTx=StartOfFrame[80]] = Port == 1 and Layer3Protocol == IPv4
Assign[StreamId=1; DestinationPort=0; Slice=StartOfFrame[64]; SliceReTx=StartOfFrame[80]] = Port == 1 and Layer3Protocol == IPv6

When a packet is transmitted, either from host or from retransmit, the FCS is normally recalculated. This results in what can seem like slightly different behavior from the SliceReTx and Slice options. For example, if both slicers are slicing from "EndOfFrame[-20]" in an IPv4 UDP packet with some payload: Slice will remove 16 bytes of data plus the 4 byte FCS. SliceReTx will remove 16 bytes of data plus the 4 byte FCS, but on retransmit the FCS is recalculated, resulting in another 4 bytes of UDP payload being overwritten, resulting in a total 20 bytes UDP payload being removed.

Assign Filters using Correlation Key

The following examples show how to assign filters with correlation key recipes. The correlation key recipe syntax can be found here.

IP frame

This simple example shows how to calculate the correlation key over an entire IP frame (i.e. frame - MAC header, padding and FCS):

Define ckRecipe = CorrelationKey(Begin=Layer3Header[0], End=Layer3PayloadEnd[0])
Assign[StreamId=0;CorrelationKey=ckRecipe;Descriptor=DYN4,ColorBits=8] = Layer3Protocol == IP

The correlation key recipe uses the "Layer3PayloadEnd" dynamic offset to ignore any potential padding between the end of layer 3 payload and beginning of FCS. By default the dynamic descriptor 4 does not include the correlation key so it must be configured to do so with the 'ColorBits' option.

UDP frame with static/dynamic masks and input length limiting

In this example a correlation key is calculated for UDP frames. The TTL and FLAG fields in the IP header are masked away using a static/pre-defined mask. The UDP checksum field is masked away using a dynamic mask. The input over which the correlation key is calculated is limited to 500 bytes.

Define ckRecipe = CorrelationKey(Begin=Layer3Header[0], End=Layer3PayloadEnd[0], KeyLength=500, StaticMask=(IPTTL,IPFLAGS), Mask1={0xFFFF0000:Layer4Header[4]})
Assign[StreamId=0;CorrelationKey=ckRecipe;Descriptor=DYN4,ColorBits=8] = Layer4Protocol == UDP

Assign Filters using Mask

The following examples show how to assign filters with mask recipes. The fuill mask recipe syntax can be found here.

Masking out byte range

Using the following NTPL, the first 16 bytes of the TCP payload will be filled with zeroes:

Define maskRecipe = Mask(Offset0=Layer4Payload[0], Length0=16)
Assign[StreamId=0;Mask=maskRecipe] = Layer4Protocol == TCP

Masking out multiple ranges

Up to three byte ranges can be masked out. In the following NTPL, bytes 0-15, 32-47 and 64-79 of frame received on port 0 will be masked out:

Define maskRecipe = Mask(Offset0=StartOfFrame[0], Length0=16, Offset1=StartOfFrame[32], Length1=16, Offset2=StartOfFrame[64], Length2=16)
Assign[StreamId=0;Mask=maskRecipe] = Port == 0

Assign Filters using HeaderStripper

The following examples show how to assign filters with headerstripper recipes. The full headerstripper recipe syntax can be found here.

Remove outer tunnel

The following filter configuration removes the outer tunnel from a frame:

Define hstRecipe = HeaderStripper(Begin=StartOfFrame[0], End=InnerLayer2Header[0])
Assign[StreamID=0; HeaderStripper=hstRecipe] = all

Replacing two bytes

The following filter configuration replaces the first two bytes of the L2 header with 0xFFFF:

Define hstRecipe = HeaderStripper(Offset0=Layer2Header[0], Cmd0=Replace2B, Value0=65535)
Assign[StreamID=0; HeaderStripper=hstRecipe] = all

GTP user plane detunnelling

The following filter configuration forwards all the traffic from port 0 to port 1 while decapsulating the GTP-U packets:

Define GTP = HeaderStripper(Begin=Layer3Header[0], End=InnerLayer3Header[0], Offset0=Layer2Header[12], Cmd0=InnerEtherType)
Assign[StreamID=Drop; Priority=0; DestinationPort=1; HeaderStripper=GTP] = Port == 0 AND TunnelType == GTPv1-U-GPDU
Assign[StreamID=Drop; Priority=1; DestinationPort=1] = Port == 0

Removing all VLAN tags (supporting MPLS packets)

The following filter removes the VLAN tags from all the traffic packets.

Define VLAN_HS = HeaderStripper(Begin=FirstVLAN[0], End=FirstMPLS[-2])
Assign[StreamID=0; HeaderStripper=VLAN_HS] = Port == 0 AND Encapsulation == VLAN AND Layer2Protocol == EtherII
The first offset points to the existing VLAN (it is important to mark the Encapsulation as VLAN).

The second offset strips up to the Layer 3 header, if MPLS is not present. If MPLS is present in the frame, it will automatically adjust the offset to be before the MPLS header. Please refer to Dynamic Offsets for more details on how to use dynamic offsets. The offset of -2 is chosen to leave two bytes from the region being stripped to be replaced by the correct EtherType. This is because the EtherType field is placed after the VLAN tag in the ethernet frame.

As a side note, if it is required to distinguish between VLAN and MPLS frames, you can detect only VLAN frames with:

Encapsulation == VLAN AND Encapsulation != MPLS

Avoiding VLAN tags while stripping GTP

The following filter shows how Offset0 can be used to avoid additions such as VLAN tags when stripping other parts.

Define GTP = HeaderStripper(Begin=Layer3Header[0], End=InnerLayer3Header[0], Offset0=Layer3Header[-2], Cmd0=InnerEtherType)
Assign[StreamID=Drop; Priority=0; DestinationPort=1; HeaderStripper=GTP] = Port == 0 AND TunnelType == GTPv1-U-GPDU
Assign[StreamID=Drop; Priority=1; DestinationPort=1] = Port == 0

Assign Filter with flow matcher

For examples of Assign command used in flow matcher applications please refer to Flow matcher feature and flowmatch/flowmatch_example_main.cpp for a C++ code example.