Knowledge base : Knowledge Base > ByteBlower > Automation > Tcl

Introduction

When you are testing your device with ByteBlower, you sometimes like to have a pcap-capture of the data for debugging purpose. With the ByteBlower API we can easly capture that network traffic and present it to you as a pcap-file. This feature will help you to debug quickly the problem with your device.

Let me explain how to do this.

Using the ByteBlower GUI

This is the simplest way of capturing traffic. Available since GUI v2.11, and server v2.9. Here you can see how it works :


Options to keep the file size manageable

With the default settings all network traffic is captured from the selected interface. Often this results in very large PCAP files. Since version 2.13 of the ByteBlower GUI, two options are open to reduce filesize:

  • Configure a BPF filter.  This filter is applied by the ByteBlower server, only traffic matching the filter is forwarded to the ByteBlower GUI.
  • Truncate individual frames. Only the first number are kept in the PCAP and the remainder is dropped.

The default settings for both is capture all traffic.

These two options are available in the advanced config part of the capture dialog. They are configured before the capture starts. Did the capture already begin? The options become editable again in dialog after stopping the capture.

Using the Remote Capture Tool

This was the easiest way of capturing traffic on your port, until we brought the capture functionality to the GUI. It's a command-line tool that can be downloaded from the setup pages. It can be used on Windows, Mac and Linux.

Note:

This tool only works on ByteBlower Server running 2.1 and higher

Using the ByteBlower lower-layer API

When you are using our TCL API to transmit your traffic you can use the Rx.Capture of a ByteBlower Port to create a capture. Using our API allows you to automate when to create a capture. Let your script determine when you need to create a capture.

All you need is the Rx.Capture.Add call on your ByteBlower Port.

Rx.Capture.Add

Just like you add a Trigger to a ByteBlower port you can add a Capture. On this capture-object you can set a capture filter and thus define which frames you would like to see captured. After that just start the capture and you are all set. Now lets put these simple words into a working script.

For this post, we assume we have created a back-to-back scenario with:

  • Two configured ByteBlower ports srcPort and dstPort
  • a stream Stream configured to flow between srcPort and dstPort

 Create a capture on the dstPort and configure it

set dstPortCapture [ $dstPort Rx.Capture.Add ]

Now you have a capture Object. Using the Tk command you can visualize it to see what you can do with this object.

Tk screenshot of Rx.Capture object

It is important to set a capture filter on this capture. This will allow you to capture only the packets you are interested in.

$capture Filter.Set "dst port 513"

The filter must be a BPF filter. On http://biot.com/capstats/bpf.html you can find more info on the syntax of these filters and some day-to-day examples.

Start the capture

You can start the capture now.

$capture Start

Now start your traffic and every frame that matches your filter will be captured. You can see how many frames have been captured with the in the result capture object

set captureResult [ $capture Result.Get ]
$captureResult Refresh
$captureResult PacketCount.Get

Stop the capture and get the PCAP-file

Like the start-method there is a stop method the capturing.

$capture Stop

To retrieve your pcap-file use the Pcap.Save method.

$captureResult Refresh
$captureResult Pcap.Save "C:/Users/Excentis/Sniffs/DeviceX.pcap"

On your disk you will find DeviceX.pcap containing the packets that matched your filter that arrived on your ByteBlower destination port (destPort). If you want, you can use Frames.Get to retrieve a TCL-list containing the packets represented in hex-encoding. This way you could use TCL to parse your retrieved packets...

API

You can find the api documentation of the RxCapture here: https://api.byteblower.com/tcl/classRx_8Capture_8RawPacket.html

Introduction

When learning a new progamming language, you always start with a Hello-world project. Mostly it is a simple exercise to learn the basics of a language. Let's do the same to start knowing the basic of the ByteBlower API in TCL. Lets make a Hello-world project - aka a simple back 2 back flow between 2 port. For this to work we need

The API documentation can be read online at http://api.byteblower.com . This tutorial is also published in the API docs at https://api.byteblower.com/tcl/bbexamples_tut.html .

Hello ( TCL ) world

The tclsh is a simple command-line interactive interpreter. You can either start it with a script on the command line, in which case it runs the script to completion and then exits, or you can start it without any arguments, in which case you will be presented with an interactive prompt, usually using a % symbol to prompt for input. In interactive mode, you can type in commands, which Tcl will then execute and display the result, or any error messages that result. To exit the interpreter, type exit and press Return. Playing around with the interactive interpreter is a great way to learn how to use Tcl. Most Tcl commands will produce a helpful error message explaining how they are used if you just type in the command with no arguments.

If you have never worked with TCL then on this page ( http://www.tcl.tk/man/tcl8.5/tutorial/tcltutorial.html ) you will find a complete tutorial covering everything you need or want to know about programming in TCL.

To continue this tutorial you only need to know the first 8 short lessons.

Hello ( ByteBlower ) world

Now that we covert the basics of TCL we can start on writing our first TCL script to send traffic between 2 ByteBlower ports. What we need are 2 ports on the Trunking interface connected back-to-back. This is a simple setup for our simple Hello-world script.

We start by starting an editor that you prefer to work with. You can use Notepad++ on windows, vim of geany on Linux or Textwrangle on Mac. We will write our lines of code in a file that we afterwards can execute. You could also type these lines directly in a Tcl-console and see the output directly on the screen.

Loading the ByteBlower API

Before we can start we need to load the ByteBlower API. This can be done simply by following lines of code.

package require ByteBlower
package require ByteBlowerHL
package require excentis_basic

The first line Package require ByteBlower will load the Lower Layer API of ByteBlower. Since this is a simple hello-world, we will load also the Higher Layer API which will help us with common tasks. More info can be found in ( background: The ByteBlower TCL API and its components )

Connect to ByteBlower

Now the API's are loaded so let's continue with our next step: connecting to the ByteBlower server. To do this, we create a ByteBlower Server Object. Once this object is created, we have a connection to our server. The parameter after "Server.Add" can be the fqdn of your ByteBlower server or even its IP-address. 

set bbServer [ ByteBlower Server.Add byteblower.lab.company.com ]

The variable $bbServer now holds our ByteBlowerServerObject. If you want, you can print out the description of this serverObject with following command.

puts [ $bbServer Description.Get ]

Every ByteBlower-object has a method Description.Get. This method will print out all information known about this object. This information will be printed in a hirachical way. So if you ask the description of a server, you will get the description of every port, which will print out the description of every flow on that port... and so on.

Create our src-port and dst-port

Now that we have a server, we will create a source port and a destination port. Step by step we will do this for the source port. For the destination port we will us the same methods. First we create our port on the server. The physical location of this port is het first port on our first trunk switch. So the name for this port is trunk-1-1 ( trunk-1 port 1 ).

set srcPort [ $bbServer Port.Create "trunk-1-1" ]

Our port is created and stored in variable srcPort. Let's move on to Layer2

set srcL2 [ $srcPort Layer2.Set ethII ]
$srcL2 Mac.Set "00ff1c000001"

Now that we have configured our Layer2 on our ByteBlowerPort we can create a Layer3. There are 2 types of Layer3 supported by ByteBlower: IPv4 and IPv6. In this example we use IPv4 But you could easly use IPv6 as well. We start by creating the Layer3 Object and then configure it with the apropriate values. 

set srcL3 [ $srcPort Layer3.Set ipv4 ]
$srcL3 Ip.Set "192.168.1.2"
$srcL3 Netmask.Set "255.255.255.0"
$srcL3 Gateway.Set "192.168.1.1"

Lets do the same for our destination port.

set dstPort [ $bbServer Port.Create "trunk-1-2" ]
set dstL2 [ $dstPort Layer2.Set ethII ]
$dstL2 Mac.Set "00ff1c000002"
set dstL3 [ $dstPort Layer3.Set ipv4 ]
$dstL3 Ip.Set "192.168.1.3"
$dstL3 Netmask.Set "255.255.255.0"
$dstL3 Gateway.Set "192.168.1.1"

So this is done. Now we have an active source-port and an active destination port. Lets create a frame we want to send and put is on this flow.

Create a Frame.

To easly create a frame, we use a procedure which is available in our excentis_basic package. This procedure will generate the bytes of our package that we can set on our flow. First we need to resolve our destination mac address. Following snippet will send an ARP request from our source port to resolve the mac-address.

#
# --- Get the destination MAC addresses for our UDP frame to reach the other port ---
#
#- Sending an Arp for the destination IP of our UDP frame.
set dmacBackToBackDestination [ $srcL3 Protocol.Arp [ $dstL3 Ip.Get ] ]

Protocol.Arp will have as effect the transmission of an ARP packet to resolve the destination. It will return the resolved mac-address ( depending on the setup: the mac-address of our destination-port or the mac-address of our gateway). If it fails, it will throw an exception. Now that we have our destination mac-address, we can generate the bytes of our frame. We will create an UDP frame of length 64 ( incl FCS ) between udp-port 2001 and 2002.

set dstUdpPort 2002
set srcUdpPort 2001
# length exclude FCS
set udpLength 60
set srcFrameContent [ Frame.Udp.Set $dmacBackToBackDestination [ $srcL2 Mac.Get ] [ $dstL3 Ip.Get ] [ $srcL3 Ip.Get ] $dstUdpPort $srcUdpPort [ list -Length $udpLength ] ]

This line of code will return the string representation of the bytes of our frame. If you want to provide UDP content you could create your frame this way

set dstUdpPort 2002
set srcUdpPort 2001
set srcFrameContent [ ::excentis::basic::Frame.Udp.Set $dmacBackToBackSource [ $srcL2 Mac.Get ] [ $dmacBackToBackSource Ip.Get ] [ $srcL3 Ip.Get ] $dstUdpPort $srcUdpPort { 0xAA 0xBB 0xCC 0xDD }

Create a Flow

Since we will use the Higher Layer API, we don't need to create all the flow-object. The HL-API will do this for us. We simple need to describe the flow, provide its characteristics. In this example we will send a 1000 frames with an interframe gap of 1ms. At the receiving side, we will count the packets that meet our filter.

set numberOfFrames 1000
set interFrameGap 1000000

set srcFlow [ list -tx [ list -port $srcPort \
    -frame $srcFrameContent \
    -numberofframes $numberOfFrames \
    -interframegap $interFrameGap \
] \
    -rx [ list -port $dstPort \
    -trigger [ list -type basic -filterFormat bpf -filter "( ip src [ $srcL3 Ip.Get ] ) and ( ip dst [ $dstL3 Ip.Get ] ) and ( udp src port $srcUdpPort ) and ( udp dst port $dstUdpPort )" ] \
] \
]

the scenario

To run our scenario we call the Higher Layer method ExecuteScenario and provide as argument our flow configuration. If we give it a list of flow configuration than all these flows will be executed.

# Sending the packet
set result [ ::excentis::ByteBlower::ExecuteScenario [ list $srcFlow ] ]
puts "Result of this back-to-back scenario:" puts "${result}"

Destroy our object

As a pragmatic programmer we must release our resources. If not, we could create a leak. To destroy all our object we just need to destroy our parent object meaning our serverObject. Every child-Object will be destroyed as well.

# Destructing our objects
$bbServer Destructor

Run the final script

Now the script is finished, we can run it. Just open a terminal and start wish84. On Windows just start wish.exe ( normally located in the start menu ).

debie@laptop:~$ wish

Now the wish is loaded, lets source our script aka hello-byteblower-world.tcl

source hello-byteblower-world.tcl

Voila your script is running, you first automated test with the ByteBlower API is created. If all is connected well you sould get some output like this

Result of this back-to-back scenario
{-tx {NrOfFramesSent 1000 ByteBlowerObject_1381496571_10 1000} -rx {NrOfFrames 1000}}

Introduction

By default, the ByteBlower Tcl/Python API is installed interactively. When starting the installer, an installation wizard is presented to the user. By going through this wizard, settings such as the installation directory can be configured.

When a graphical environment is present on the system (e.g. Windows or a desktop version of a Linux distribution), an installer window is shown. In a non-graphical environment, the same questions are asked in the console, where the user can specify custom values.

To easily deploy the Tcl API/Python API application automatically across multiple devices in a controlled environment, a unattended (or non-interactive or quiet) installer is available.

Note: for a similar article about the GUI installer, see here.

Unattended mode

To run the installer in unattended mode, simply run the installer executable as a command and add the unattended option.

Note the API can only be installed by a superuser (i.e. a system-wide install).

Linux TCL-API(e.g. 64 bit):

$ ./ByteBlower-API-Tcl-linux-x86_64-installer.run --mode unattended
(returns when finished, no output)

Linux Python-API(e.g. 64 bit):

$ ./ByteBlower-API-Python-linux-x86_64-installer.run --mode unattended
(returns when finished, no output)

Windows TCL-API

> ByteBlower-API-Tcl-windows-x86-installer.exe --mode unattended
(returns immediately, run in background, no output) 

Windows Python-API

> ByteBlower-API-Python-windows-x86-installer.exe --mode unattended
(returns immediately, run in background, no output)

MacOS TCL-API(from 10.6 Snow Leopard on):

$ open ./ByteBlower-API-Tcl-osx-installer.app --args --mode unattended
(returns when finished, no output)

MacOS Python-API(from 10.6 Snow Leopard on):

$ open ./ByteBlower-API-Python-osx-installer.app --args --mode unattended
(returns when finished, no output)

Mac OS X (pre 10.6 Snow Leopard):

$ ./Byteblower-API-Tcl-osx-installer.app/Content/MacOS/installbuilder.sh --mode unattended
(returns when finished, no output)

Running the unattended installation has the following effects:

  • default installation directory is used
    • Windows 32-bit: C:\Program Files\Excentis\ByteBlowerTcl
    • Windows 64-bit: C:\Program Files (x86)\Excentis\ByteBlowerTcl
    • Linux superuser (system-wide): /opt/Excentis/ByteBlowerTcl
    • Mac OS X: /Applications/Excentis/ByteBlowerTcl
  • default directory for the Tcl packages is used
  • all components are installed
  • only the API library for the native system is installed
  • if an existing installation is found at the default directory, it is silently uninstalled!

In exactly the same way, the application can be silently uninstalled. For example for a Linux user-wide installation:

$ /opt/Excentis/ByteBlowerTcl/uninstall --mode unattended
(returns when finished, no output)

Customization in unattended mode

Sometimes the default installer settings are not desirable. They can be overridden by providing additional command-line arguments to the installer.

The following arguments can be used:

  • --prefix (default the system-default): override the installation directory
  • --tcl_pkg_path (default searches the system for relevant Tcl path): the directory to install the tcl packages; this should be part of the Tcl path
  • --disable-components (default none): disable components by adding a comma-seperated list of the following values
    • runtimedocs: Runtime help for all ByteBlower API calls
    • byteblowerhl: A higher-layer Tcl API, to speed up the creation of complex testing scenarios
    • examples: Example scripts using the higher-layer Tcl API
  • --llInstallWin32 (default selected if matching system): enable or disable installation of the ByteBlower lower-layer API for Windows
  • --llInstallLinux32 (default selected if matching system): enable or disable installation of the ByteBlower lower-layer API for 32-bit Linux
  • --llInstallLinux64 (default selected if matching system): enable or disable installation of the ByteBlower lower-layer API for 64-bit Linux
  • --llInstallMacosx (default selected if matching system): enable or disable installation of the ByteBlower lower-layer API for Mac OS X

For example, on a Linux system:

$ ./ByteBlower-API-Tcl-linux-x86-installer.run --mode unattended --prefix /mnt/software/byteblower/tcl --disable-components examples --tcl_pkg_path /mnt/tcllib/packages
(returns when finished, no output)

Note you can show all command-line options using the --help option.

Troubleshooting

Tcl installation not found

Question: You encounter the following message
No valid TCL installation was found. Please provide the path to the Tcl executable.

Answer: Is Tcl installed on your system? If yes you will need to use the graphical mode on you systen, This mode will request the path to the Tcl executable with a pop-up.

No such file or directory

Question: What does this error mean?
./ByteBlower-API-Tcl-linux-x86-installer.run: No such file or directory

Answer: Use the 64bit installer on a 64bit Linux system. The 32bit can't run.

Introduction

FrameTags are used to overwrite parts of a frame with dynamically generated data, such as a timestamp. This data is calculated for each individual frame in a frame blasting stream, just before it leaves the ByteBlower server.

Consider a ByteBlower Port on which a Tx.Stream is created. A Frame object is added to the stream. The content of a frame is static and can be set using the Bytes.Set function. The following code shows how to create this situation in the Tcl API:

Tcl
set flowObject [ $sourcePortObject Tx.Stream.Add ]
set frameObject [ $flowObject Frame.Add ]
$frameObject Bytes.Set $byteFrame

The static bytes of a frame can be changed by calling the Bytes.Set function again. This can be done at all times, even while the Tx.Stream is being transmitted!

However, changing the static bytes of a frame is a client-side action. FrameTags allow changing the frame content automatically and at the server side.

Adding a FrameTag to a Frame object causes the following things to happen for each individual frame in the traffic stream:

  • The ByteBlower server determines the tag value, immediatly before a frame is to be transmitted.
  • The ByteBlower server inserts the tag value into the frame, overwriting the static bytes located at the tag's location.
  • The ByteBlower server sends the resulting frame.

This entry will show...

  • how to add a frame tag to a frame object
  • where those tags are placed by default and how to override this position
  • how to tell the receiving side where in the received frame to look for a tag

Types of FrameTags

Currently two FrameTags exist:

  • The TimeTag is used for latency measurements and contains a timestamp value. The server automatically determines it by looking at its clock for each frame sent in the stream.
  • The SequenceTag is used for out of sequence detection and contains a frame counter value. The server automatically increments it for each frame sent in the stream.

To perform latency measurements or out of sequence detection, the test scenario needs to be configured at two different places:

  1. At the TX side, we need to add the FrameTag(s) to the Frame object.
  2. At the RX side, we need to create the appropriate receiver(s) on the incoming packets. This causes the server to read a tag from the received frames and interpret them (e.g. by calculating latency based on the timestamps).

Adding a FrameTag to a Frame

Adding a FrameTag to a Frame object is very simple. Just retrieve the relevant FrameTag object on the frame and enable it

Tcl
set timeTagObject [ $frameObject FrameTag.Time.Get ]
$timeTagObject Enable

Note that there are deprecated functions to enable a specific tag directly from the frame object. These are only preserved for backwards compatibility and their behaviour is identical to the two lines of code above.

Tcl
$frameObject TimeTag.Enable

Adding multiple FrameTags is also possible.

Tcl
[ $frameObject FrameTag.Time.Get ] Enable
[ $frameObject FrameTag.Sequence.Get ] Enable

FrameTag properties

Every FrameTag has a fixed set of properties:

  • Metrics: Contains two values defining the external tag structure.
    • Alignment: Defines at which positions, relative to the start of the frame, the tag value can be inserted. A value of 1 means the tag value can inserted at any byte. A value of 4 means the tag can only be inserted at bytes 4, 8, 12, etc.
    • Length: Shows the number of bytes in the frame that will be overwritten by the tag. As shown in the tag insertion mechanism, this is not always a contiguous range!
  • Position: Defines at which byte the tag starts, relative to the end of the frame. The position is defined from the back, because the frame headers may change during transmission (e.g. a VLAN tag might be added). This would change the tag position relative to the front of the frame.
  • Format: This code defines the internal format of the tag (e.g. whether the timestamp is shown in nanoseconds or microseconds).

Apart from the position, which can be explicitly set, these properties properties have fixed values and defined by two things:

  • the type of tag (e.g. a TimeTag)
  • the transmitting server type (e.g. a 1x00 server)

The current tag metrics are:

1000 series
  Alignment Length
TimeTag 1 8
SequenceTag 1 8
2000 series
  Alignment Length
TimeTag 1 8
SequenceTag 1 8

The current TX tag formats are:

1000 and 2000 series (pre-1.10.18 version)
  Format (string)
TimeTag TimeStamp-Microseconds_CRC
SequenceTag SequenceNumber-0_CRC
1000 and 2000 series (post-1.10.18 version)
  Format (string)
TimeTag TimeStamp-10Nanoseconds
SequenceTag SequenceNumber-0_CRC

Note that in future multiple tags and even metrics may be supported by the various server types (either at the TX side, the RX side or both sides). This could allow some interoperability between server series.

FrameTag insertion mechanism

When the alignment value is 1, the tag can be inserted into the frame at every byte. The tag is inserted as follows:

  1. Start at the back of the frame.
  2. Go back position bytes.
  3. The tag value starts at that location and continues for length bytes.

Requirement: The tag position should always be larger than its length. If a smaller position is set, an error will be thrown (even if that FrameTag is currently disabled).

FrameTag insertion example for alignment 1

 

Multiple tags

Multiple tags can be added into a single frame object. Each of them has its own position. When a tag is enabled, the necessary bytes in the frame are reserved for that tag. For an alignment value of 1, this means bytes [position, position-length[ will be reserved.

Requirement: The positions of all enabled tags must be chosen so that their reserved spaces do not overlap. Enabling a FrameTag whose reserved space would overlap with another enabled FrameTag's reserved space will throw an error.

Automatic position

Automatic placement of FrameTags has multiple advantages:

  • it shields the API user from the complexity described above
  • it makes sure the requirements are respected: the position will always be larger than the tag length and multiple tags will never overlap
  • it places the tags as close towards the end as possible to allow tagging small frames without overwriting frame headers

Example 1: Full automatic behaviour

The tags are placed at the end of the frame.

If both are enabled, the SequenceTag is placed in front of the TimeTag:

  TimeTag only SequenceTag only Both
TimeTag position 8 N/A 8
SequenceTag position N/A 8 16

FrameTag automatic insertion - 1300 - Both tags automatic

Example 2: TimeTag has an explicit position

The explicit position is always respected.

If the TimeTag position is greater than or equal to 16, the SequenceTag can be placed behind it (at the end of the frame). If the position is less than 16, the SequenceTag is placed right in front of the TimeTag.

The same goes for a SequenceTag with an explicit position.

FrameTag automatic insertion - 1300 - One tag fixed

Minimally required frame sizes

Positioning FrameTags automatically places them as close to the end of the frame as possible.

Even so, tagging takes up space, so our frame should have at least a minimal payload so the frame headers are not overwritten.

The table below shows the minimal frame size for various frame header and tagging combinations:

Headers header length no tags TimeTag SequenceTag both tags
EthII-IPv4-UDP 14+20+8=42 42* 50* 50* 58*
EthII-IPv4-TCP 14+20+20=54 54* 62 62 70
EthII-IPv6 14+40=54 54* 62 62 70
EthII-IPv6-UDP 14+40+8=62 62 70 70 78
EthII-IPv6-TCP 14+40+20=74 74 82 82 90

(*) No valid Ethernet frame (smaller than 60 bytes)Frame smaller than 60 bytes, the minimum frame size required by the Ethernet specification.

Passing FrameTag settings to RX side(s)

Adding a TimeTag or SequenceTag to a Frame object is not enough to perform latency or out of sequence detection tests.

At the receiving ByteBlower port, a corresponding receiver must be created. Adding receivers for both can be done as follows:

Tcl
set latencyObject [ $destinationPortObject Rx.Latency.Add ]
set outofsequenceObject [ $destinationPortObject Rx.OutOfSequence.Add ]

We will not discuss how to use these receivers here. See the relevant posts on latency and out of sequence detection tests for more information. 

What is important is how to pass the TimeTag and/or SequenceTag information (at the TX side) to a Latency and/or OutOfSequence receiver (at the RX side). This is needed because:

  • The receiver must know where within the frame he must look for a tag.
  • This cannot be done at the server side, because the receiving port may be located on another server. Even when tags are placed automatically, the generated tag position should be passed to the receiver.
  • In future, multiple tag metrics and/or tag formats may be supported. When using non-default properties, this should be passed to the receiver.

The default metric and format values are the same as the default TX values for that server type (see above). Note that in future, servers may have support for multiple metrics and formats and that RX support may differ from TX support. For example, a server may need an alignment of 8 to insert a TimeTag, while being able to read TimeTags at any position.

The default position values are:

1000 series
  Position
TimeTag 8
SequenceTag 8
2000 series
  Position
TimeTag 8
SequenceTag 8

These values correspond with the automatic positions when the frames are used by themselves.

However, if both tags are enabled, the SequenceTag position will be 16 by default. In this case (even though both frames are positioned automatically), the default RX settings will be incorrect!

Therefore, passing the FrameTag properties to the RX side, should always be done explicitly by the client script. This is the safest option and works in all situations.

For a situation where both tags are used, this can be done as follows:

Tcl
$latencyObject FrameTag.Set [ $frameObject FrameTag.Time.Get ]
$outofsequenceObject FrameTag.Set [ $frameObject FrameTag.Sequence.Get ]

Introduction

ByteBlower allows performing both latency measurements and out-of-sequence detection on a stream of traffic.

This guide will show you how to set up such a scenario using the ByteBlower API and how to retrieve and interpret the results.

Using the ByteBlower lower-layer API

We start by setting up a normal frame blasting scenario.

For this post, we assume we have created a back-to-back scenario with:

  • two configured ByteBlower ports srcPort and dstPort
  • a valid byteframe byteFrame that will be sent between the two

Setting up the TX side

Latency and out-of-sequence measurements work by inserting FrameTags into the network packet.

Such tags are applied to a Frame object, which is itself part of a traffic stream (Tx.Stream). First we set up these objects:

Tcl
set stream [ $srcPrt Tx.Stream.Add ]
set frame [ $stream Frame.Add ]
$frame Bytes.Set $byteFrame

Then we enable one or more tags on the frame object:

  • For latency measurements, we enable the time tag of the frame which contains a timestamp.
  • For out-of-sequence measurements, we enable the sequence tag which contains a sequence number.
  • Note that both tags can be enabled simultaneously!
Tcl
set timetag [ $frame FrameTag.Time.Get ]
$timetag Enable
set sequencetag [ $frame FrameTag.Sequence.Get ]
$sequencetag Enable

Now every frame sent by the server will contain the enabled tags.

The structure of these tags and their position within the frame may depend on the ByteBlower server type and which other tags are enabled.

By default, the ByteBlower server will place the tags automatically at an optimal position. For a background post about what actually happens when enabling frame tags and how to configure the tag properties, see XXX.

Setting up the RX side

At the receiving ByteBlower port, we need to add an incoming packet processor.

  • For latency measurements, two types of processors exist: 
    • Rx.Latency.Basic (default) which calculates the minimal, average and maximum latency and the jitter
    • Rx.Latency.Distribution which creates a latency histogram
  • For out-of-sequence detection a single processor exists:
    • Rx.OutOfSequence.Basic which calculates the number of frames that arrived out of order

We add such incoming packet processors to the receiving port.

Tcl
set latencyProcessor [ $dstPort Rx.Latency.Add basic ]
set latencyDistProcessor [ $dstPort Rx.Latency.Add distribution ]
set outofsequenceProcessor [ $dstPort Rx.OutOfSequence.Add ] 

The receiving side must know what tag to look for and where within the frame it can be found. Note that the receiving port may be located on another server and even on a server of a different type!

That is why we always pass the TX frametag information to the RX side in our client script. This will correctly set up the receiving side.

Tcl
$latencyProcessor FrameTag.Set [ $frame FrameTag.Time.Get ]
$latencyDistProcessor FrameTag.Set [ $frame FrameTag.Time.Get ]
$outofsequenceProcessor FrameTag.Set [ $frame FrameTag.Sequence.Get ]

Now we are ready to begin sending the traffic! If the frame tag properties of the transmitting and receiving servers are not compatible, an error will be shown at runtime.

Interpreting the results

After the scenario is finished, we can query the incoming packet processors their result values. The structure of this result depends on the type of incoming packet processor. This is done by calling the following methods:

Tcl
% puts $latencyProcessor Counters.Get
NrOfFrames 20 MinLatency 62 AvgLatency 63 MaxLatency 69 Jitter 1

% puts $latencyDistProcessor Counters.Get
[0 - 1000[ us} 56 {[1000 - 2000[ us} 23 {[2000 - 3000[ us} 4 ... {[998000 - 999000[ us} 0 {[999000 - 1000000[ us} 0 {< 0 us} 0 {> 1000000 us} 0

%
puts $outofsequenceProcessor Counter.Get
FramesOutOfSequence 0 NrOfFrames 100

We can just print these counters or process them further, based on our scenario.

Using the ByteBlower higher-layer API

For simple tests, using the higher-layer API simplifies the configuration significantly.

Scenario configuration

todo

Interpreting the results

todo

Introduction

ByteBlower allows the user to configure different parameters of the DHCP and DHCPv6 protocol.

This guide explains what parameters exist and how they can be configured through the ByteBlower API.

Different parameter types

Retransmission policy

Both the DHCPv4 and DHCPv6 protocol have different stages, in which information is requested from the DHCP server, and an answer is expected. If the answer is not received within an acceptable time, the client must retransmit its request. The maximum number of retries,  the maximum duration, ... are all parameters described in the next section. The policy defines how the client will react on a time-out: will it wait longer, will it wait the same amount of time, ... These questions are the responsibility of the retransmission policy. Currently, the following policies are supported:

  • Fixed timing

    This type of retransmission policy will use the same time-out for each retry. It is a simple policy, which consists out of two parameters:

    • (Initial) time-out
    • Maximum retries
  • RFC suggested

    This type of retransmission policies are more advanced, and described in RFC2131 for DHCPv4 and RFC3315 for DHCPv6. Each time a request times out, the next time-out is increased. To make sure that two different clients starting at the same time are not sending each retry at the same time, a random variable is used to divert the time-out values.

    The following parameters are defined:

    • Initial time-out
    • Maximum retries
    • Maximum duration (DHCPv6)
    • Maximum time-out (DHCPv6)
  • A detailed description of these parameters is provided below.

For both DHCPv4 and DHCPv6, the following methods exist:

RetransmissionPolicy.Set.FromString

This will set the retransmission policy. The following values are supported:
  • RfcSuggested
  • FixedTiming/li>

RetransmissionPolicy.String.Get

This returns the current configured retransmission policy.

Timing parameters

The retransmission policy above already reveals the different timing parameters which exists. ByteBlower goes one step further and allows you to define each parameter in each stage of the protocol.

Meaning of the different parameters

Initial time-out

The initial time-out is the time-out value for the first attempt in each stage. If the first attempt fails, the retransmission policy will decide if a new attempt is required, and will calculate the new time-out value.

This parameter is used for both the fixed timing and RFC suggested retransmission policy.

Maximum retries

Both retransmission policies accept a maximum number of retries. When this maximum is reached, no further attempts will be tried and an error is returned.

This parameter is used for both the fixed timing and RFC suggested retransmission policy.

Maximum duration

The RFC suggested retransmission policy excepts a maximum duration parameter. This parameter defines the maximum allowed total duration of all attempts in the specified stage.

This parameter is only used by the RFC suggested retransmission policy for DHCPv6.

Maximum time-out

This parameter defines an absolute maximum value for the calculated time-out.

This parameter is only used by the RFC suggested retransmission policy for DHCPv6.

DHCPv4 parameters

DHCPv4 has the following configurable stages in ByteBlower:

  • Discover stage
  • Request stage

For each of these stages, you can set the initial time-out and the maximum retries, as shown below:

Discover.InitialTimeout.Set and Discover.InitialTimeout.Get

With these two methods, you can set the value or get the current configured value for the time-out value during the DHCPv4 solicit stage.

  • Units
    By default, the unit is nanosecond, but with the set command, you can provide the unit.
    E.g. Discover.InitialTimeout.Set 2 s
  • Default value: 1 s
  • Valid range: 1 - 4,294,967,295

Discover.MaxRetries.Set and Discover.MaxRetries.Get

These methods can be used the Set or Get the maximum number of retries in the discover stage.

  • Default value: 5
  • Valid range: 1 - 4,294,967,295
  • Request.InitialTimeout.Set and Request.InitialTimeout.Get

    With these two methods, you can set the value or get the current configured value for the time-out value during the DHCPv4 solicit stage.

    • Units
      By default, the unit is nanosecond, but with the set command, you can provide the unit.
      E.g. Discover.InitialTimeout.Set 2 s
    • Default value: 1s
    • Valid range: 1 - 4,294,967,295

    Request.MaxRetries.Set and Request.MaxRetries.Get

    These methods can be used the Set or Get the maximum number of retries in the request stage.

  • Default value: 5
  • Valid range: 1 - 4,294,967,295
  • DHCPv6 parameters

    For DHCPv6, you can configure the parameters for the following stages:

    • Solicit stage
    • Request stage
    • Confirm stage
    • Renew stage
    • Inform stage

    For each stage, the values can be get and set using the following methods:

    <<StageName>>.InitialTimeout.Set and <<StageName>>.InitialTimeout.Get

    For each stage, the initial time-out can be set using these methods.

    • Units
      By default, the unit is nanosecond, but with the set command, you can provide the unit.
      E.g. Solicit.InitialTimeout.Set 2 s
    • Default value:
      • Solicit: 1 s
      • Request: 1 s
      • Confirm: 1 s
      • Renew: 1 s
      • Inform: 1 s
    • Valid range: 1 - 4,294,967,295 nanoseconds

    <<StageName>>.MaxTimeout.Set and <<StageName>>.MaxTimeout.Get

    For each stage, the maximum time-out can be set using these methods.

    • Units
      By default, the unit is nanosecond, but with the set command, you can provide the unit.
      E.g. Solicit.MaximumTimeout.Set 2 s
    • Default value:
      • Solicit: 120 s
      • Request: 30 s
      • Confirm: 4 s
      • Renew: 600 s
      • Inform: 120 s
    • Valid range: 1 - 4,294,967,295 nanoseconds

    <<StageName>>.MaxRetries.Set and <<StageName>>.MaxRetries.Get

    For each stage, the maximum number of retries can be set and get using these methods.

    • Default value:
      • Solicit: 65535
      • Request: 100
      • Confirm: 65535
      • Renew: 65535
      • Inform: 65535
    • Valid range: 1 - 4,294,967,295

    <<StageName>>.MaxDuration.Set and <<StageName>>.MaxDuration.Get

    For each stage, the maximum duration can be set and get using these methods.

    • Units
      By default, the unit is nanosecond, but with the set command, you can provide the unit.
      E.g. Solicit.MaximumDuration.Set 30 s
    • Default value:
      • Solicit: 30 s
      • Request: 30 s
      • Confirm: 10 s
      • Renew: 65535 s
      • Inform: 65535 s
    • Valid range: 1 - 4,294,967,295 nanoseconds

    Introduction

    TCL tricks

    tclsh vs wish

    tclsh is a shell-like application that reads Tcl commands from its standard input or from a file and evaluates them. If invoked with no arguments then it runs interactively, reading Tcl commands from standard input and printing command results and error messages to standard output. It runs until the exit command is invoked or until it reaches end-of-file on its standard input. If there exists a file .tclshrc (or tclshrc.tcl on the Windows platforms) in the home directory of the user, tclsh evaluates the file as a Tcl script just before reading the first command from standard input.

    Wish on the other hand is a simple program consisting of the Tcl command language, the Tk toolkit, and a main program that reads commands from standard input or from a file. It creates a main window and then processes Tcl commands. If wish is invoked with arguments, then the first few arguments, ?-encoding name? ?fileName? specify the name of a script file, and, optionally, the encoding of the text data stored in that script file. A value for fileName is recognized if the appropriate argument does not start with “-”.

    If there are no arguments, or the arguments do not specify a fileName, then wish reads Tcl commands interactively from standard input. It will continue processing commands until all windows have been deleted or until end-of-file is reached on standard input. If there exists a file “.wishrc” in the home directory of the user, wish evaluates the file as a Tcl script just before reading the first command from standard input.

    If arguments to wish do specify a fileName, then fileName is treated as the name of a script file. Wish will evaluate the script in fileName (which presumably creates a user interface), then it will respond to events until all windows have been deleted. Commands will not be read from standard input. There is no automatic evaluation of “.wishrc” when the name of a script file is presented on the wish command line, but the script file can always source it if desired.

    Note that on Windows, the wishversion.exe program varies from the tclshversion.exe program in an additional important way: it does not connect to a standard Windows console and is instead a windowed program. Because of this, it additionally provides access to its own console command.

    Tcl under Linux

    When starting tclsh under Linux, you can't use history ( arrow-up key ). But because history is very handy you can use the rlfe-tool to regain history. 

    rlfe lets you use history and line-editing in any text oriented tool. This is especially useful with third-party proprietary tools that cannot be distributed linked against readline. It is not perfect but it works pretty well.
    (source: manpage rlfe)

    Ubuntu/debian installation and use:

    debie@laptopdebie:~/ sudo apt-get install rlfe debie@laptopdebie:~/ rlfe tclsh

    Show loaded libs

    When you want to know if ByteBlower API is loaded you can use the following command:

    % info loaded

    This will return a list describing all of the packages that have been loaded into the interpreter. When the ByteBlower API was loaded you should find in the list an entry looking like this

    {/usr/local/share/tcltk/ByteBlowerLL/linux/x86_64/default/libbbapi.so Bbapi} {/usr/local/share/tcltk/ByteBlowerLL/linux/x86_64/libtbcload-1.7.so Tbcload}

    Show tcl version

    To know the version of your TCL, just execute following simple command in the tclshell. The returnvalue will be the version

    % info tclversion
    8.5

     

    ByteBlower API Tricks

    --help

    Getting help on a method. Assume you have a ByteBlower Object, lets say ByteBlowerServer Object. If you want to know the syntax of a particular method or the description of what this method does, you can ask with --help. Example:

    % set server [ ByteBlower Server.Add byteblower-dev-1-1.lab.byteblower.excentis.com
    ByteBlowerObject_1385568352_2
    % $server Port.Create --help
    ByteBlowerServer {
    Parameters:
    interface: Interface on which the ByteBlower port must be created.
    Description: 
    Creates a ByteBlower port on the ByteBlower server on the given interface.
    Returns: 
    The new ByteBlower port.
    }
    %

    Now we know that PortCreate creates a ByteBlower Port on the ByteBlower server and that we need to give 1 parameter: the interface. So the command will look like this

    % set server [ ByteBlower Server.Add byteblower-dev-1-1.lab.byteblower.excentis.com
    ByteBlowerObject_1385568352_2
    % $server Port.Create trunk-1-1 ByteBlowerObject_1385568352_3 %

    Description.Get

    An other helpfull method of any ByteBlowerObject is the Description.Get method. This will return a full description of the object.

    % $port Description.Get
    ByteBlowerPort: {
    Name: trunk-1-1
    EthernetConfiguration: {
    Encoding: DIX
    MAC: 00:FF:1C:00:00:01
    }
    IPv4Configuration: {
    Gateway: 10.1.1.1
    IP: 10.1.1.5
    Netmask: 255.255.255.0
    }
    }

    Introspector

    The introspector is a unique way to visualize the ByteBlower objects. Every ByteBlower-object has next to the method Description.Get a method Tk. Executing this method on a ByteBlower Object will reveal the Introspector.

    The introspector consists out of 2 main parts. Left you find the class method tree. This tree contains all the public available methods in alphabetical order. On the right is the result window. Here you will find the result of the evocation of a method in the introspector on this object. On the bottom you will find the inputfield you can use to execute a method on this object.

     

    ( Blogpost Charlie !!! )

    Introduction

    FrameTags are added to a ByteBlower Frame object and can be used to automatically insert dynamic information into the different frames of a ByteBlower traffic stream.

    Consider a ByteBlower Port on which a Tx.Stream is created. A Frame is added to the stream. The content of a frame is static and can be set using the Bytes.Set function. The following code shows how to create this situation in the Tcl API:

    Tcl
    set flowObject [ $sourcePortObject Tx.Stream.Add ]
    set frameObject [ $flowObject Frame.Add ]
    $frameObject Bytes.Set $byteFrame

    The static bytes of a frame can be changed by calling the Bytes.Set function again. This can be done at all times, even while the Tx.Stream is being transmitted! However, changing the static bytes of a frame is a client-side action. FrameTags allow changing the frame content automatically and at the server side.

    Adding a FrameTag to a Frame object causes the following things to happen for each individual frame in the traffic stream:

    • The ByteBlower server determines the tag value, immediatly before a frame is to be transmitted.
    • The ByteBlower server inserts the tag value into the frame, overwriting the static bytes located at the tag's location.
    • The ByteBlower server sends the resulting frame.

    This entry will show...

    • how to add a frame tag to a frame object.
    • how frame tags are structured and what their properties are. Note that this may depend on the type of the (transmitting) ByteBlower server!
    • where those tags are placed by default and how to override this position. Note this may depend on the type of the (transmitting) ByteBlower server!
    • how to tell the receiving side where in the received frame to look for a tag.

    Types of FrameTags

    Currently two FrameTags exist:

    • The TimeTag is used for latency measurements and contains a timestamp value. The server automatically determines it by looking at its clock for each frame sent in the stream.
    • The SequenceTag is used for out of sequence detection and contains a frame counter value. The server automatically increments it for each frame sent in the stream.

    Note that to perform latency measurements and/or out of sequence detection, the test script needs to be configured at two different places:

    1. At the TX side, we need to add the FrameTag(s) to the Frame object. This causes the server to insert the tag before transmission.
    2. At the RX side, we need to create the appropriate receiver(s) on the incoming packets. This causes the server to read a tag from the received frames and interpret them (e.g. by calculating latency based on the timestamps).

    This post only describes the TX side! See relevant posts on latency and out of sequence detection for more information.

    Adding a FrameTag to a Frame

    Adding a FrameTag to a Frame object is very simple. Just retrieve the relevant FrameTag object on the frame and enable it

    Tcl
    set timeTagObject [ $frameObject FrameTag.Time.Get ]
    $timeTagObject Enable

    Note that there are deprectated functions to enable a specific tag directly from the frame object. These are only preserved for backwards compatibility and their behaviour is identical to the two lines of code above.

    Tcl
    $frameObject TimeTag.Enable

    Adding multiple FrameTags is also possible.

    Tcl
    [ $frameObject FrameTag.Time.Get ] Enable
    [ $frameObject FrameTag.Sequence.Get ] Enable

    FrameTag properties

    Every FrameTag has a fixed set of properties:

    • Metrics: Contains two values defining the external tag structure.
      • Alignment: Defines at which positions, relative to the start of the frame, the tag value can be inserted. A value of 1 means the tag value can inserted at any byte. A value of 4 means the tag can only be inserted at bytes 4, 8, 12, etc.
      • Length: Shows the number of bytes in the frame that will be overwritten by the tag. As shown in the tag insertion mechanism, this is not always a contiguous range!
    • Position: Defines at which byte the tag starts, relative to the end of the frame. The position is defined from the back, because the frame headers may change during transmission (e.g. a VLAN tag might be added). This would change the tag position relative to the front of the frame.
    • Format: This code defines the internal format of the tag (e.g. whether the timestamp is shown in nanoseconds or microseconds).

    Apart from the position, which can be explicitly set, these properties properties have fixed values and defined by two things:

    • the type of tag (e.g. a TimeTag)
    • the transmitting server type (e.g. a 1x00 server)

    The current tag metrics are:

    1000 series
      Alignment Length
    TimeTag 1 8
    SequenceTag 1 8
    2000 series
      Alignment Length
    TimeTag 8 8
    SequenceTag 1 8

    The current tag formats are:

    1000 series (pre-1.10.18 version)
      Format (enum) Format (string)
    TimeTag TimeStamp_Microseconds_CRC TimeStamp-Microseconds_CRC
    SequenceTag SequenceNumber_0_CRC SequenceNumber-0_CRC
    1000 series (post-1.10.18 version)
      Format (enum) Format (string)
    TimeTag TimeStamp_10Nanoseconds TimeStamp-10Nanoseconds
    SequenceTag SequenceNumber_0_CRC SequenceNumber-0_CRC
    2000 series
      Format (enum) Format (string)
    TimeTag TimeStamp_10Nanoseconds TimeStamp-10Nanoseconds
    SequenceTag SequenceNumber_0_CRC SequenceNumber-0_CRC

    Note that in future multiple tags and even metrics may be supported by the various server types (either at the TX side, the RX side or both sides). This could allow some interoperability between server series.

    FrameTag insertion mechanism

    This section will explain exactly how a tag is inserted into a frame.

    Case 1: Alignment value is 1

    When the alignment value is 1, the tag can be inserted into the frame at every byte. The tag is inserted as follows:

    1. Start at the back of the frame.
    2. Go back position bytes.
    3. The tag value starts at that location and continues for length bytes.

    Requirement: The tag position should always be larger than its length. If a smaller position is set, an error will be thrown (even if that FrameTag is currently disabled).

    FrameTag insertion example for alignment 1

    Case 2: Alignment value is greater than 1

    When the alignment value is greater than 1, the exact position of the tag value cannot be determined by the API. Specifically, when a FrameSizeModifier is applied to the frame, the tag position (which is a constant offset relative to the end of the frame), will be located at different positions relative to the start of the frame when the frame size changes.

    This means an extra offset is needed and that this extra offset can vary between different frames.

    The tag is inserted as follows:

    1. Start at the back of the frame.
    2. Go back position bytes.
    3. Go towards the front of the frame until the first aligned position and remember the offset between the position of the FrameTag and this aligned position (denoted as x in the pictures).
    4. The tag value starts at this aligned location.
    5. Go to byte position+length and store this offset (x).

    Requirement: The tag position should always be larger than its length. If a smaller position is set, an error will be thrown (even if the FrameTag is currently disabled!)

    FrameTag insertion example for alignment greater than 1

    The best case occurs, when the position matches the frames alignment. In this case:

    • the extra offset is 0 
    • the total space required to place the tag is its length

    FrameTag insertion example for alignment greater than 1 - best case

    The worst case occurs, when the position points to 1 byte before the frames alignment. In this case:

    • the extra offset is alignment - 1
    • the total space required to place the tag is length + alignment - 1

    FrameTag insertion example for alignment greater than 1 - worst case

    Multiple tags

    Multiple tags can be added into a single frame object. Each of them has its own position and based on that position, some space in the frame is reserved for it. The reserved space is equal to the maximum space that could be needed in the worst aligning situation.

    The interval for the worst alignment case of a FrameTag is equal to [position+alignment-1, position-length[. When the alignment is 1, this boils down to [position, position-length[ as one might expect. Note that in these intervals the left boundary is larger then the right, because a larger value means closer to the start of the frame.

    FrameTag reserved tag space

    Requirement: The positions of all enabled tags must be chosen so that their reserved spaces do not overlap. Enabling a FrameTag whose reserved space would overlap with another enabled FrameTag's reserved space will throw an error.

    Automatic position

    Automatic placement of FrameTags has multiple advantages:

    • it shields the API user from the complexity described above
    • it makes sure the requirements are respected: the position will always be larger than the tag length and multiple tags will never overlap
    • it places the tags as close towards the end as possible to allow tagging small frames without overwriting frame headers

    The automatic behaviour is determined by the transmitting server type. The general principles that define the automatic behaviour are:

    • If a single tag is enabled, its position is length. This makes sure it is placed completely at the back of the frame.
    • If both TimeTag and SequenceTag are enabled and both are positioned automatically, will be placed next to each other at the back of the frame.
    • If both TimeTag and SequenceTag are enabled and one of them has an explicit position, the other tag will be placed as close to the rear as possible:
      • If there is enough place after the fixed tag to fit (the worst case of) the automatic tag, the automatic tag will be placed behind it and as much to the end as possible.
      • If there is not enough place after the fixed tag to fit (the worst case of) the automatic tag, the automatic tag will be placed immediately before the fixed tag.

    1000 series examples

    In the 1000 series both tags have an alignment of 1. This means we can place both tags at any position in the frame.

    Example 1: Full automatic behaviour

    The tags are placed at the end of the frame. If both are enabled, the SequenceTag is placed before the TimeTag:

      TimeTag only SequenceTag only Both
    TimeTag position 8 N/A 8
    SequenceTag position N/A 8 16

    FrameTag automatic insertion - 1300 - Both tags automatic

    Example 2: TimeTag has an explicit position

    The explicit position is always respected. If the TimeTag position is greater than or equal to 16, the SequenceTag can be placed behind it. If it is less than 16, the SequenceTag is placed right in front of the TimeTag.

    Note this works in a similar manner when the SequenceTag has an explicit position.

    FrameTag automatic insertion - 1300 - One tag fixed

    2000 series examples

    In the 2000 series the TimeTag has an alignment of 8, while the SequenceTag has an alignment of 1. 

    Example 1: Full automatic behaviour

    Tags are placed at the end of the frame. If both tags are enabled, the TimeTag is placed before the SequenceTag. Note this is the opposite from the 1000 series! We place the SequenceTag last, because it has an alignment of 1 and thus has a fixed length.

      TimeTag only SequenceTag only Both
    TimeTag position 9 N/A 17
    SequenceTag position N/A 8 8

    FrameTag automatic insertion - 2100 - Both tags automatic

    Example 2: TimeTag has an explicit position

    The explicit position is always respected. If the TimeTag position is greater than or equal to 17, the SequenceTag can be placed behind it. If not, the SequenceTag is placed in front of it. Note that when its placed in front of it, it respects the reserved interval of the TimeTag!

    FrameTag automatic insertion - 1300 - One tag fixed

    Minimally required frame sizes

    Positioning FrameTags automatically places them as close to the end of the frame as possible. Even so, tagging takes up space, so our frame should have at least a minimal payload so the frame headers are not overwritten.

    The table below shows the minimal frame size for various frame header and tagging combinations:

    1000 series
    Headers header length no tags TimeTag SequenceTag both tags
    EthII-IPv4-UDP 14+20+8=42 42* 50* 50* 58*
    EthII-IPv4-TCP 14+20+20=54 54* 62 62 70
    EthII-IPv6 14+40=54 54* 62 62 70
    EthII-IPv6-UDP 14+40+8=62 62 70 70 78
    EthII-IPv6-TCP 14+40+20=74 74 82 82 90
    2000 series
    Headers header length no tags TimeTag SequenceTag both tags
    EthII-IPv4-UDP 14+20+8=42 42* 57* 50* 65
    EthII-IPv4-TCP 14+20+20=54 54* 65 62 73
    EthII-IPv6 14+40=54 54* 65 62 73
    EthII-IPv6-UDP 14+40+8=62 62 73 70 81
    EthII-IPv6-TCP 14+40+20=74 74 89 82 97

    Note that frame sizes with an asterisk (*) are smaller than 60 bytes, the minimum frame size required by the Ethernet specification.

    Passing FrameTag settings to triggers at the RX side

    Adding a TimeTag or SequenceTag to a Frame object is not enough to perform latency or out of sequence detection tests. At the receiving ByteBlower port, a corresponding receiver must be created. Adding receivers for both can be done as follows:

    Tcl
    set latencyObject [ $destinationPortObject Rx.Latency.Add ]
    set outofsequenceObject [ $destinationPortObject Rx.OutOfSequence.Add ]

    We will not discuss how to use these receivers here. See the relevant posts on latency and out of sequence detection tests for more information. 

    What is important is how to pass the TimeTag and/or SequenceTag information (at the TX side) to a Latency and/or OutOfSequence receiver (at the RX side). This is needed because:

    • The receiver must know where within the frame he must look for a tag.
    • This cannot be done at the server side, because the receiving port may be located on another server. Even when tags are placed automatically, the generated tag position should be passed to the receiver.
    • In future, multiple tag metrics and/or tag formats may be supported. When using non-default properties, this should be passed to the receiver.

    The default metric and format values are the same as the default TX values for that server type (see above). Note that in future, servers may have support for multiple metrics and formats and that RX support may differ from TX support. For example, a server may need an alignment of 8 to insert a TimeTag, while being able to read TimeTags at any position.

    The default position values are:

    1000 series
      Position
    TimeTag 8
    SequenceTag 8
    2000 series
      Position
    TimeTag 9
    SequenceTag 8

    Note these values correspond with the positions of the tags when they are used by themselves and positioned automatically. Note, that these default RX settings are always incorrect when using multiple FrameTags in a frame, even when all of them are positioned automatically by the server!

    Therefore, passing the FrameTag properties to the RX side, should always be done explicitly by the client script. For a situation where both tags are used, this can be done as follows:

    Tcl
    $latencyObject FrameTag.Set [ $frameObject FrameTag.Time.Get ]
    $outofsequenceObject FrameTag.Set [ $frameObject FrameTag.Sequence.Get ]

    We to help you!