How to Script Large Ixia Breaking Point Network Profiles Part 2: Electric Boogaloo


Hello everyone, hope you’re doing well today. Before reading this blog post, I recommend you read my previous blog post that describes the problem my team was trying to solve and documents our solution to this problem.

How to Script Large Ixia Breaking Point Network Profiles

Did you read it? Good!

After posting that blog post, someone who works for Keysight (Ixia’s parent company) reached out to us to let us know there may be other (and potentially better) ways to solve our problem. This blog post describes the process we built for doing the exact same thing, only using the built-in Breaking Point Library (written in TCL). It will also discuss the pros and cons we’ve seen of this approach so far.

How to Use the Script

The script and supporting files are available for download here:

1. Import IPSec_Template.bpt into your Breaking Point
  1. Sign into the Breaking Point GUI and do the following
  2. Test–>Import Test
  3. Give it a name, choose the file, and click upload.
  4. Opening the test should give you an empty test, with a network neighborhood that only has 4 interfaces and nothing else
2. Copy the script file and the CSV to the via scp.
  1. Winscp to the device
  2. Copy the files to the proper directory (for me its /home/admin)
3. Run the script.
  1. SSH into the device
  2. Type in “Enter BPS” The shell should now read ” bps> “
  3. From the BPS shell, type in: “bpsh BlogPost_TCLScript.tcl”
  4. This should run the script. The script will save the Network Neighborhood to the name specified in the “newTestName” variable.
  5. The output on your screen should look something like these two screenshots

How Does the Script Work?

At a very high level, this script does the following:

  1. Loads a template test called “IPSec_Template” which needs to exist on the system before this script can be run.
  2. Creates a temporary network neighborhood in memory based on the network neighborhood that was in the “IPSec_Template” test.
  3. Loads a CSV called IPSecScaling_Small.csv from the directory you are in on the Breaking Point. This CSV has values in it that can be used to create a network neighborhood.
  4. The script creates whatever entries are contained in the CSV file and names the new network neighborhood “”TCL_Scripting_IPSecExample” or whatever you decide to change the “newTestName” variable to.

Each function from this script will be explained in this section. Most of them wind up making a list of a certain “type” that needs to be created, and then an accompanying function to import that list, and create it:

proc drawLogo null {

This draws the SealingTech logo! There isn’t really anything out of the ordinary in this function besides this line:

puts \033\[2J

I would be lying to you if I told you I know exactly what it means, but my research told me that it can be used to clear the screen on certain “UNIX Based OSes”. It appears to clear the screen when I use PuTTy from Windows. If it doesn’t work in your environment, everything may wind up looking really ugly when the script runs.

proc createVlanList {csvFilePath}

This process parses a CSV and returns a list that is made up only of entries that had “VlanInt” in the “Type” column

    set vlanLst []
    set file [open $csvFilePath]
    while {[gets $file line] >=0 } {
        set newvar [split $line ,]
        set name [lindex $newvar 0]
        set container [lindex $newvar 1]
        set type [lindex $newvar 5]
        if {$type eq "VLANInt"} {lappend vlanLst "$name,$container,$type"}
    return $vlanLst

The way it works is pretty simple, it creates a variable called “file” which is representative of the file that is located at $csvFilePath. For every line in that file, it splits the CSV into several different variables(name, container, and type). If the “type” variable is “VLANInt” it adds the variables to a new list which is composed only of “vlanInt” objects. This list will be used later in the script to actually create the vlan objects

proc createVlanObjects {uniqueVlans newNet}

Remember in that last function when I said the VLAN List would be used later? This is where it gets used! Its worth noting that “uniqueVlans” is a list of vlan objects created in the previous function.

“newNet” is a variable that is created by one of the built-in Breaking Point functions. It represents the network neighborhood from the test that this script uses as a template.

    set iteration 1
    set counter 1
    foreach line $uniqueVlans {
        #assigns each CSV column to a variable
        set newvar [split $line ,]
        set vlan [lindex $newvar 0]
        set interface [lindex $newvar 1]
        #Formats a proper MAC address for the VLAN Interface.   The Counter and Iteration are used to increment the proper part of the MAC address.   format %02x converts a decimal to hex(with a leading zero if applicable)
        set MACKEY2 [format %02x $counter]
        set MACKEY3 [format %02x $iteration]
        set CreateMAC "02:1a:c5:00:$MACKEY3:$MACKEY2"
        if {$counter !=200} {set counter [expr $counter + 1]}
        if {$counter == 200} {set counter 1;set iteration [expr $iteration + 1]}
        #Creates a few more variables needed to create the VLAN interface in the newNet Network neighborhood
        set stringLength [string length $vlan]
        set vlanNumber [string range $vlan 4 $stringLength]
        set interface [string tolower $interface]
        $newNet add vlan -id $vlan -default_container $interface -inner_vlan $vlanNumber -mac_address $CreateMAC
    return $newNet

You can see the for-loop in this is very similar to the way we read files in the previous function. It goes through the file line by line and assigns variables from each part of the list.

The next section looks very complicated, but it accomplishes a very simple function. It creates unique mac addresses for each of the VLAN entries. The last part of the hex changes in every iteration of the loop. Every 200 iterations, the second to last part of the hex will change. For example, the MACKEYs will look something like:


From there, this function is fairly straightforward. The remaining parts of the function are used to create the VLAN Objects in a network neighborhood.

$newNet add vlan -id $vlan -default_container $interface -inner_vlan $vlanNumber -mac_address $CreateMAC

You’ll notice that these parameters all match up to something you would see in the Breaking Point GUI in the “VLAN” portion of a network neighborhood.

proc createStaticHostList {csvFilePath}

This function is very similar to “createVlanList”. This does the same thing as that function, but with entries from the CSV that are typed “staticHost”

proc createStaticHosts {staticHosts newNet}

This function is very similar to “createVlanObjects”. There are less formatting things that need to be done in the function, but it eventually creates the static host objects that would be part of the Network Neighborhood in the Breaking Point.

$newNet add ip_static_hosts -id $name -tags $name -default_container $container -ip_address $ipAddr -netmask "" -count $count

Again, you’ll notice that these parameters all match up to something you would see in the Breaking Point GUI in the “VLAN” portion of a network neighborhood.

proc createIPSecRouterList {csvFilePath}

This function is very similar to “createVlanList” and “createStaticHostList”. This does the same thing as those functions, but with entries from the CSV that are typed “IPSecRTR”

proc createIPSecRouterObjects {ipSecRouterList newNet}

This function is very similar to “createVlanObjects” and “createStaticHosts. A notable difference is that this needs to create an IPSec configuration first before the Router objects can be created. We only needed one for our testing so it was hard coded into the code

$newNet add ipsec_config -id "ipsec_config 1" -ike_version "2" -psk "aaa" -ike_dh "5" -ike_encr_alg "ENC_AES256_CBC" -ike_auth_alg "AUTH_HMAC_SHA2_256_128" -ike_prf_alg "PRF_HMAC_SHA2_256" -ike_lifetime "86400" -esp_encr_alg "ENC_AES256_CBC" -esp_auth_alg "AUTH_HMAC_SHA2_256_128" -ipsec_lifetime "86400" -setup_timeout "600" 

Again, you’ll notice that these parameters all match up to what an IPSec configuration looks like within the Breaking Point Network Neighborhood setup.

This piece of the code creates the actual IPSec Router Objects. Notice that it references the ipsec configuration that was created earlier in the function.

$newNet add ipsec_router -id "$name" -default_container $container -ip_address $ipAddr -gateway_ip_address $gateway -netmask $netmask -ike_peer_ip_address $gateway -ipsec "ipsec_config 1"


Main isn’t really a function in TCL, but its whatever the script runs automatically when it is called. I put in a commented section to refer to it as “main” but that holds no true significance in the program.

This first section of code uses the built in Breaking Point functions to create some variables necessary for the testing:

set testInstance [$bps createTest -name TCL_Testing -template IPSec_Template]
set templateNetworkName [$testInstance cget -neighborhood]
set newNet [$bps createNetwork -template $templateNetworkName]

When you first type in “enter bps” in the SSH Prompt on the Breaking Point, it automatically creates the “$bps” variable. This variable is actually an “object” . Not sure if objects are a real construct in TCL or not, but that is what I will call them for the remainder of this post. This “object” can be used to implement many functions that can pull information from, or make changes to, the Breaking point device.


This is a built-in Breaking Point function that can be used to create an object in your shell session that holds all of the values of a created test. The example code creates a new object called “testInstance” which is a copy of a test that already exists on the BreakingPoint device called “IPSec_Template”.

set testInstance [$bps createTest -name TCL_Testing -template IPSec_Template]


This is a built-in Breaking Point function that can be used to grab various objects from a test. I haven’t found a lot of documentation on exactly what this can do, but in this command its used to copy the name of the “network neighborhood” object that was part of the previously defined “testInstance” object. This will be used in the next function to create a copy of whatever network neighborhood was in the originally copied test template

set templateNetworkName [$testInstance cget -neighborhood]


This is a built-in Breaking Point function that can be used to create a new Network Neighborhood object within your SSH session. This object can be viewed and edited many times. Once all the changes are made, this object also has a “save” command which will be used to save it to the device.

set newNet [$bps createNetwork -template $templateNetworkName]

This command sets the variable “newNet” to be a copy of the Network Neighborhood that is named in “$templateNetworkName”

Setting some additional variables

#Set the file path for the CSV and the name of the new Network Neighborhood that will be created
set csvFilePath ./IPSecScaling_Small.csv
set newTestName "TCL_Scripting_IPSecExample"

This section creates variables that are used further down in the script.

csvFilePath is the full Linux directory location of the CSV that will be used to generate the Network Neighborhood. We used the relative path here, but it could also be something like : “/home/admin/IPSecScaling_Small.csv”

newTestName is the name that your new Network Neighborhood will have after the test is completed.

Actually Doing Stuff!

#Save the new network with the name described
drawLogo 1
puts "Creating VLAN List.  The current time is [clock format [clock seconds] -format %R]"; set vlanLst [createVlanList $csvFilePath]
puts "Creating Router List.  The current time is [clock format [clock seconds] -format %R]";set ipSecRouterList [createIPSecRouterList $csvFilePath]
puts "Creating Static Host List.  The current time is [clock format [clock seconds] -format %R]";set staticHostList [createStaticHostList $csvFilePath]
puts "Creating VLAN Objects.  The current time is [clock format [clock seconds] -format %R]";set newNet [createVlanObjects $vlanLst $newNet]
puts "Creating IPSecRouterObjects.  The current time is [clock format [clock seconds] -format %R]";set newNet [createIPSecRouterObjects $ipSecRouterList $newNet]
puts "Creating Static Hosts.  The current time is [clock format [clock seconds] -format %R]";set newNet [createStaticHosts $staticHostList $newNet]
puts "Saving the Network Neighborhood.  The current time is [clock format [clock seconds] -format %R]";$newNet save -name $newTestName

This section of code implements the functions that have been described in near excruciating detail further up in this post. Each line pretty much says what its doing.

Some additional notes:

“puts” is the command used to print output to the screen in TCL.

The “clock format [clock seconds] –format %R” portion grabs the current time from the device, then prints it to the screen in a readable format. %R formats the as %H:%M

This line is the most important piece of code in the entire script!

$newNet save -name $newTestName

It saves the network neighborhood that all of the other parts of “Main” have been creating and editing. If you look carefully, you’ll notice this same “$newNet” object is sent to all of the “create” functions in the script. It accumulates the changes, and then the changes are made to the Breaking Point device when the “save” command is implemented.

Pros and Cons

Both this approach, and the approach my team created in our previous blog post have pros and cons. Neither way seems to be without issues. This section will define the pros and cons of this approach vs the original approach my team used.


  • This method is supported / recommended by Ixia.
  • In theory, this method should continue working between device updates due to utilizing Ixia’s prebuilt commands and APIs to invoke changes.
  • This method is simpler than reverse engineering and re-generating the XML files that contained all of this information previously.
  • Platform-Independent. Our previous approach used Windows Powershell to generate an XML file.
    • If not working from Windows, or a system that implements Powershell in some way, the original approach would not be feasiable.
    • All this approach needs is a system that can SSH into the Breaking Point device. This can be done via PuTTy in Windows, and natively via SSH in Linux.


  • Speed
    • Our original use case for this script was to generate something like 40 thousand different IPSec VPN connections. When I tried to use this script to generate that amount, it appeared to be doing roughly one static host per second. This would mean it would take about 11 hours to run. The XML generation via Powershell was significantly faster ( I don’t have a benchmark handy but it was probably about 10-15 minutes at the most)
    • If someone has an idea about how to make that portion of this script run fast, please let us know!
      • I experimented a bit with trying to send a list to the “newNet add ip_static_hosts” function but didn’t have much luck.
  • Usability
    • I don’t have any hard data to back this up, but I’m going to go out on a limb and say more people are probably familiar with Powershell and XML than TCL. Despite the task at hand being more difficult to implement in Powershell.
  • Lack of Documentation
    • This is really a con for both approaches I suppose. I had a very difficult time finding any documentation on how to use the built-in Breaking Point functions. There are a few blog posts on their website (linked in this blog post) but not much else that I was able to find.
    • I did find some good documentation on the TCL language although some implementations on the device seemed to vary from what I saw in documentation. (linked in this post)

Additional Notes

  • I knew nothing about TCL going in, but here are some notes about it:
    • It’s a case sensitive language (or at least it is on the Breaking Point)
    • As far as I can tell, processes always need to have a variable sent to them. You’ll see “null” written in some of my functions, and when I call them I just pass them the number 1
    • “puts” is how you print to the screen, but there is some weird behavior with the way printing to the screen works in this language
      • I found it to be interchangeable with “echo” sometimes, but not others
      • Using quotes (i.e. “aslkjd”) prints but also allows things like variable substitutions and newlines (i.e. /n/n)
      • Using curly braces (i.e. {hello}) prints everything inside them literally. I used them for the logo drawing function.
      • When grabbing input, you sometimes need to “flush” the screen or else the prompts you are trying to print will happen after the input grabbing…. I do not know why, but I’m sure someone who is better than me at IT does.
        • This can be done with the command “flush stdout”
    • When declaring variables, don’t use a $. When referencing variables, use the $. Some functions such as “lindex” require to use the $ when referencing the variables. Others like “lappend” don’t.
  • We were also recommended to use some Python scripts that interact with the Breaking Point API. These scripts are provided by Ixia/Breaking Point
    • Unfortunately when I tried these out, it looks like they had options to retrieve, create, and modify objects but not in the way that we needed to do it.
      • Again, there wasn’t a lot of documentation on this, so if someone has had success with this method, please let us know!
  • I am planning on writing a script for my team that will allow easy automation for creation of Network Neighborhoods and Tests, and also allow automation of running tests sequentially and recording the data we need. If that comes to fruition, it may be posted here in another blog post. If anyone is interested in that, please let me know.


I did a lot of googling to discover some references and as previously stated was directed to some links by someone who works for Keysight. Links to what I’ve referenced can be found here:

TCL Documentation:

Breaking Point Documentation

Supporting Files Download Link

Posted in