Creating custom indexes to data with Swift Sets

Creating custom indexes to data with Swift Sets

Introduction & Background

I have been working on a flow visualization tool for a while now. It is part of a project where a datacenter has evolved over a long time and has grown into a complex myriad of connections, applications and “solutions” to make things work. Goal of the project is to visualize certain environments and how they communicate with other services. Surely we’ve looked at Tetration as a Service and other visualization tools. The business case wasn’t viable enough for commercial solutions, so decided to go with Elastiflow as a basis.

Personal note: It’s been way overdue for a blog post. Even though Tom (@networkingnerd) mentioned that many bloggers have found it hard to find the time and drive to write blog posts during COVID19, WFH and everything that comes with it, I have been frustrated over myself I haven’t found the drive to write for way too long. 

It works well for forensics but for the original purpose (visualization, research & analysis) it was lacking a few bits. It was thus decided that a custom-made application that takes the samples from ElastiFlow and work from there was the most viable road. And so I started writing a Mac Application, using Core Data and GraphViz to fetch samples, process them (dedup), and were able to visualize flows. 

Fast forward to just before summer break; the flows in the database have grown to millions of records, which led to huge delays (300s) for the visualization of the flows on a larger dataset of server IPs. The reason for that is twofold, database queries are always more expensive than in-memory searches and the way I organized the data (in-memory) was inefficient. I’ve solved the latter by optimizing the code structure and algorithm and reduced the visualization time from 300s to 25s per visualization iteration. But the first cause of delays (roundtrips to the database) isn’t solved with that optimization and it bit me in ingesting new samples (as that also checks the database for duplicate samples). The solution to that is to use an in-memory database (this is quite common; Cisco ISE has an in-memory database (I think Cisco Prime Infrastructure does too), and big data platforms like SAP/HANA). After a quick research for in-memory Swift based databases, I decided to build my own Swift based memory manager for just the flows.

Sets in Swift, Hashable, and my idea

Swift has a number of ways to create collections of data elements (classes or structures). The most common approach is an array, which is an ordered collection. It is very easy to use an array, as the example below shows.

Swift Arrays are not fixed in size, and it’s easy to add or remove elements to that array. Ideal for data manipulation and search. But.. the search is linear and takes, on average, half of the iterations to find the entry, but worst case it will take n-iterations (where n is the size of the array) to find the record you’re looking for. 

So to optimize the search speed, we need to reduce the number of iterations needed to find a specific flow. This is where the Set class comes into play. The Swift Set class is used to store unique data elements. The uniqueness is determined by the hash of a unique identifier (the key). Hashing is a mathematical method that creates a unique consistent value for a piece of data. It’s a common principle in not only encryption (integrity validation), but also in database search optimizations.

Instead of comparing all attributes in a record (let’s say a flow), the Set class checks the unique identifier if the element is inside the collection:

Using the Set swift class allowed me to do that optimization from 300seconds to 25seconds for visualization. So why not use the Set Class to store the flows. So I can definitely use that in the in-memory database of flows. In my application I use four categories of queries / searches on those flows:

  1. Full flows: Search for all attributes of a flow (protocol, source IP and Port, destination IP and Port) 
  2. Similar flows: Search for all flows for the same protocol, same source IP and to a specific destination IP and Port
  3. IP conversations: Search for flows only based on source and destination IP
  4. Server applications: Search for all flows matching a specifc destination IP and Port

Effectively these four types of searches are similar to four indices in a database, and I should be able to implement them inside Swift. And this is where the power of class inheritance and protocols come into play inside the Swift language. The Set class requires that the element inside the collection conforms to the Hashable and Equatable protocol (Hashable inherits from Equatable). It means that every element you want to store in a Set needs to minimally have the following functions:

func hash(into: inout Hasher)
static func  == (Self,Self) -> Bool

All common types in Swift (String, Int, Date) have a default implementation of these methods, so you can compare types ( == keyword is actually a function ) and use the Set class in your code. The default hash and == function implementations take all attributes and use them for comparison. 

But it is possible to override that behavior by specifically implementing the Hashable protocol and write your own implementation (and thus specify which properties are used for uniqueness)

The problem

So I wrote the following code to create the indices:

// Base class for storing network flows in memory
class FMMFlowEntry : Hashable, CustomStringConvertible {
    var proto : String = ""
    var srcIP : String = ""
    var srcPort : Int = 0
    var dstIP : String = ""
    var dstPort : Int = 0
    var firstSeen : Date?
    var lastSeen : Date?
    static func == (lhs: FMMFlowEntry, rhs: FMMFlowEntry) -> Bool {
        let response = dstIP == rhs.dstIP && proto == proto && dstPort == dstPort && srcIP == srcIP && srcPort == rhs.srcPort
        return response
    public func hash(into hasher: inout Hasher) {
        hasher.combine(srcPort )
    var description : String {
        let response : String = "\(proto) \(srcIP):\(srcPort) -> \(dstIP):\(dstPort)"
        return response
    init(proto: String, srcIP: String, srcPort: Int, dstIP : String, dstPort: Int) {
        self.proto = proto
        self.srcIP = srcIP
        self.srcPort = srcPort
        self.dstIP = dstIP
        self.dstPort = dstPort
    init() {

// Class that represents a flow record based on source IP address and destination IP address
class FMMIPFlow  : FMMFlowEntry  {
    var refCount : Int = 1
    init(from: FMMFlowEntry) {
        super.init(proto : from.proto, srcIP : from.srcIP, srcPort : from.srcPort, dstIP : from.dstIP, dstPort : from.dstPort)


    override public func hash(into hasher: inout Hasher) {
    static func == (lhs: FMMIPFlow, rhs: FMMIPFlow) -> Bool {
        let response = lhs.dstIP == rhs.dstIP && lhs.srcIP == rhs.srcIP
        return response
    override var description : String {
        let response : String = "\(srcIP) -> \(dstIP) [\(refCount)]"
        return response

In the above code there is the base class (FMMFlowEntry) that has all necessary attributes. The hash function specifies which properties of the flow are used to determine if it is unique). The == function also uses those attributes to check for equality.

The class FMMIPFlow inherits every method and property from FMMFlowEntry. It then overrides the hash function that only the srcIP and dstIP attributes are used for hashing and comparison. 

This should mean that if I’d compile and run the code below, the variable uniqueIPFlows would only have one entry (as the srcIP and dstIP are the same for the two added flows). When I run it in Playground, this is the result.

That means that both flow1 and flow4 are added to the Set. I was not expecting that, I created a custom hash function and so it should not add it, right? For debugging I ran it again, printing the hash value too:

So even while they have the same hash value (which changes every time I run the code), both flows are still added to the index. That is not the purpose, but why?

Cause of the problem

The answer to that took me quite a while and would like to share it here. The problem lies in the comparison function. It is defined as a static function (conform to the protocol). The static keyword also means final and cannot be overridden. So even if I have a new static == function in the subclass, it will never be called because static implies final (and the compiler will just ignore that other method). We can validate that by adding a print in our code:

static func == (lhs: FMMFlowEntry, rhs: FMMFlowEntry) -> Bool {
    print("FMMFlowEntry == func called")
    let response = lhs.dstIP == rhs.dstIP && lhs.proto == rhs.proto &&
         lhs.dstPort == rhs.dstPort && lhs.srcIP == rhs.srcIP &&
         lhs.srcPort == rhs.srcPort
    return response

And rerun the code

So the hash is used for searching, but to determine if an element needs to be added to the Set, there is an equality check. And because the two flows are different (on source port), both are added. 

The solution

Now that we know the cause, we can create a solution to work around that blockade. Instead of performing the comparison check inside the static function, I can create an instance function that is called on the lhs parameter and validates against the rhs, so that I am able to override that function in a subclass. The code in FMMFlowEntry is changed:

static func == (lhs: FMMFlowEntry, rhs: FMMFlowEntry) -> Bool {
    return lhs.equals(to: rhs)
func equals(to rhs: FMMFlowEntry) -> Bool {
    let response = dstIP == rhs.dstIP && proto == rhs.proto && 
        dstPort == rhs.dstPort && srcIP == rhs.srcIP && 
        srcPort == rhs.srcPort
    return response

and the code inside the FMMIPFlow Class is changed to:

override func equals(to rhs: FMMFlowEntry) -> Bool {
    guard let rhs = rhs as? FMMIPFlow else { return false }
    let response = self.dstIP == rhs.dstIP && self.srcIP == rhs.srcIP
    return response

Now when we try to run the following code, the static compares in the base class should call the overriden equals function of the instance (FMMIPFlow in this case) and will only check for the srcIP and dstIP property, which should lead to only one entry in the Set:

Succes! Now I can create indexes / search types very quickly by just subclassing the base record and override the equals function for that specific index. Which allows me to to code the indexes I need with only a few lines of code and still be able to work with the Set class and have speed in search queries. One step closer to my in-memory database that is capable of storing millions of flows.


The key lesson here is that the keyword static in Swift means that it is a final method and cannot be overridden in a subclass. The method around it is to call an Instance method in the base class and override this in the subclass.

The Swift Playground used in this post is available on github

Tampering Visibility by Tempered Networks Airwall Solution

Tampering Visibility by Tempered Networks Airwall Solution

“Personal Note: Ok, this post has been lying around in my draft for quite some time. Sorry for that Tom, Ben, and Tempered. Too many reasons but one of them is also that the folks at Tempered were so kind to allow me a trial for a few months. I will share my experiences in a few posts to come. “

I don’t know if the organizers of Security Field Day 3 did this on purpose, but it looks like they kept a very innovative solution as encore with Tempered Networks. Their presentation was the last one in the line-up and presentations. And since I hadn’t heard about their company name, I looked them up in advance and was intrigued in how they could twist the tale on security without visibility. Todays common sensus in security is that you need to see and know what is happening on your network; Tempered says: what you cannot see, you cannot hack.

Personally I think their solution originated from the IoT/OT network environment where applying security to IoT devices is well, near impossible. The S of security is lacking in IoT for a reason. I can assure you, also from my own environment, that many IoT/OT devices do not follow RFC’s completely, let alone implement IEEE standards like Port-Based Network Access Control (IEEE 802.1X). Their paradigm is that if you place one or more sensors of such an OT network behind a device that basically hides / blinds them from the rest of the IT network, and create an overlay to wherever you have servers they need to connect to, again protected by either a hardware device or software, the communication between the two endpoints is both secure and hidden. Those ports, with often unencrypted traffic, are just not available to the generic IT network and thus less prone to intrusion events.

Their solution consists of Airwall agents that run on almost any client OS (ok, ChromeOS is a different story for any client) , hardware solutions (called gateways with also added functionality), Airwall Server agents that you can run on server OS like Linux, and a conductor from which you manage the clients and settings. Secure tunnels are created between two airwalls if traffic is allowed and defined in the conductor. That is quite similar to SD-WAN solutions or VPN solutions, isn’t it?


However, there is a big but in here too. Airwall gateways can also act / be configured as relay client. In other words, if two airwall clients (for example an agent and server) cannot contact each other directly (NAT, twice-NAT or port-blocking), and both airwall clients can connect to a third client, that third client will act as a relay point for the traffic between the two clients, it is like a smart SD-WAN Hub/Spoke and Mesh network combined! And I can share something with you, it really works.

The screenshot below shows a group I created to allow access to a virtual server with a relay VM that allows traffic between my mobile clients and that server.

In summary, I think that Airwall is one of the first true SASE clients out there, enabling end user devices (close to anyone) connectivity to any cloud, virtual server, or datacenter with some clicks inside the Conductor. I will be honest, the folks at Tempered have shared an evaluation license so that I can test out their software and solution for a few months. I have been testing it out over the past months and will share some use cases and setup experiences in a few upcoming posts.

“Hey Juniper, How’s the security state of my network?”

“Hey Juniper, How’s the security state of my network?”

Most of us probably have asked Siri, Alexa, Google some questions and answers over the past years; Smart assistants are one of those new interactions. And honestly, not that many questions you asked were probably related to networks, were they? And yet, after hearing Juniper present at Security Field Day 3, these type of questions might in the near future become a normal way to allow you to interact with the network. Sounds like something from Star Trek, and is just science fiction? I beg to differ for a number of reasons. 

Before I dive into Juniper’s security strategy, let’s first review the current state of Artificial Intelligence (AI) and Machine Learning (ML) as a concept. To do that, I will explain what happens when you ask Siri to do something or a question like what is the date?.  

First of all, after you’ve asked the question, that audio bit (which is just a record of frequencies) is guessed into a sentence. It is a form of translation, where Machine Learning is used to do well-calculated guesses in what kind of word you tried to pronounce. And I can tell you that if English is not your native tongue, some weird word-guesses come out.


Once there is a digital sentence, another process is used to narrow down your digital sentence into a single pattern-matched result. This allows you to say things like “create a meeting on date X, Y or z”.
The model uses the pattern “create a meeting” for the match and the other values are stored in variables.

After a pattern has been matched, the code corresponding to that pattern is executed. The result of that code will be a string/sentence. That sentence is then being translated to audio using Text-To-Speech and read out loud to you.

This is a perfect flow for a single sentence / command /question. But many of these smart assistents start to show real issues once you start to create related questions, like you can do with a toddler.  And that is because the flow I described above does not have that much space for relaying context between flows. So most models in these smart assistents are built / designed for a single task, and if you put them in sequence, it appears as if the assistent is “smart”. But it is not (yet).

Yes, developments go fast, and I heard last year in San Jose a great story of self-learning models and also the core faults that are inside these models because of the way the models are designed and built. But that is a completely other discussion. 

But if AI/ML is not that far ahead yet, how would you then be able to ask Juniper about the security state of the network? That how is one of the things Juniper told at Security Field Day 3.

They leverage the power of AI/ML (and that is to have more answers than just a yes or now) in their security solutions for only a predefined, supervised, set of options. Juniper uses models (they call them supervised models) to analyse metadata about the flows in your network to detect malware and other anomalies in your network, just like other network and security vendors have done. Juniper has adopted AI/ML on detecting anomalies or other weird behaviour on your network. And that can help you a lot in gaining more visibility and control in your network.

Because with everything connected to the network, increased security by leveraging encryption, more data in the cloud, we as a human are reaching our limits in finding anomalies or odd behaviors by hand. A simple computer, using a properly tuned model, can find those anomalies much faster. And because that model does that, you can focus on determining whether that anomaly is really an anomaly of yet another new application on the network.

And if you would trust those reports blindly, you can of course automate actions, but personally I am always careful with those. Suppose it is the CEO’s smartphone, you might want to call the CEO first before you throw him off the network.

Personally I do believe firmly in that AI/ML can help you in your daily job in finding those odd behaviors that without them you’d never be able to spot and help you in providing a better, smoother, more stable and secure network. But you do need to keep in mind that it is still a computer that presents you information from a lot of data and that presentation will be biased.

But definitely a good thing that Juniper has started to embrace that principle across their portfolio. 
That can bring them quite a bit.

And to be able to ask Juniper about the security state of the network? That would be not that hard to implement, because JunOS has API’s from the start. Just build an application and integrate it with existing API’s for smart assistents. If you want to see a demo, just watch this video taken from a presentation where I asked Siri how many clients were connected to the network.

Finding out which MIBs are supported on your Cisco device

Finding out which MIBs are supported on your Cisco device

Recently fellow champion Ioannis Theodoridis asked around how to find out what SNMP MIB’s are supported by a specific Cisco network device. And although model driven telemetry is gaining momentum, many monitoring systems still rely on SNMP. And finding those MIB’s can be a challenge. I found out a very easy method to quickly find which MIBs are supported. 

To get started, you need your CCO credentials by hand and an outbound FTP client. In this blog I’m using the terminal app on my mac.

1. Connect via FTP to and login with your own CCO credentials, set FTP to passive

					pr-mbp15-001:Desktop nefkensp$ ftp
Connected to
220-	Cisco Systems File Transfer Service.
--- SNIP ---
220 FTP Server (Apache/2.2) ready.
Name ( nefkensp
331 Password required for nefkensp
230 User nefkensp logged in
ftp> passive
Passive mode on.

2. now go to the directory “/pub/mibs/supportlists”


					ftp> cd /pub/mibs/supportlists
250 CWD command successful.

3. Do a directory listing (long) and enter the directory for your device. The device listing is long, I selected a new Cat9k switch in this example 

					ftp> ls
200 PORT: Command successful
150 Opening ASCII mode data connection for file list
drwxrwxr-x    2 swdsadm  cisco        4096 Jan  7  2002 2948g-13
drwxrwxr-x    2 swdsadm  cisco        4096 Jan  8  2002 4908g-13
drwxrwxr-x    2 swdsadm  cisco        4096 Dec 20  2000 90i
drwxrwxr-x    2 swdsadm  cisco        4096 Apr 19  2011 CTXSystem
drwxrwxr-x    2 swdsadm  cisco        4096 Jan  6  2003 ONS15530
drwxrwxr-x    3 swdsadm  cisco        4096 Dec 20  2000 accessProEC
drwxrwxr-x    3 swdsadm  cisco        4096 Dec 20  2000 accessProRC
drwxrwxr-x    2 swdsadm  cisco        4096 Aug 13  2008 ace
--- SNIP ---
drwxrwxr-x    3 swdsadm  cisco        4096 Oct 27  2006 wsc6009
drwxrwxr-x    2 swdsadm  cisco        4096 Oct 27  2006 wsc6503
drwxrwxr-x    2 swdsadm  cisco        4096 Oct 27  2006 wsc6504
drwxrwxr-x    3 swdsadm  cisco        4096 Oct 27  2006 wsc6506
drwxrwxr-x    3 swdsadm  cisco        4096 Oct 27  2006 wsc6509
drwxrwxr-x    2 swdsadm  cisco        4096 Oct 27  2006 wsc6513
drwxrwxr-x    2 swdsadm  cisco        4096 Dec 20  2000 wsc8510csr
drwxrwxr-x    2 swdsadm  cisco        4096 Apr 11  2001 wsc8510msr
drwxrwxr-x    2 swdsadm  cisco        4096 Dec 20  2000 wsc8540csr
drwxrwxr-x    2 swdsadm  cisco        4096 Apr 11  2001 wsc8540msr
drwxrwxr-x    2 swdsadm  cisco        4096 Jan  9  2008 xr12000
226 Transfer complete.
ftp> cd cat9300
250 CWD command successful.

4. Do a directory listing and fetch that HTML file and logout

					ftp> ls
227 Entering Passive Mode (72,163,7,54,102,29)
150 Opening ASCII mode data connection for file list
-rw-r--r--    1 swdsadm  cisco       15983 Jan 29  2018 CAT9300.html
226 Transfer complete.
ftp> get CAT9300.html
227 Entering Passive Mode (72,163,7,54,102,32)
150 Opening ASCII mode data connection for CAT9300.html
226 Transfer complete.
16159 bytes received in 0.169 seconds (93.1 kbytes/s)

5. Open the HTML file in your favorite browser and voila, you have the supported MIB directory for that network device type

Below are two samples of the supported MIBs for the Cat9300 family and the Nexus 3000 family. 


I have found this method very easy to find which MIBS are supported by any cisco device. It is an easy way to get that comprehensive list of supported MIBs. If you want to download them for your own NMS, you can go to the SNMP Object navigator and download the supported MIBS as next step.

Finding out which MIBs are supported on your Cisco device

Upgrading Firepower1010 to 6.5

The Cisco FirePower 1010 appliance (FP1010, successor to the ASA5506 which can run FTD 6.3 and higher) has finally become available. As I am relocating to a new home, it was time to replace my trusty 5506-X with the FP1010 and get a new fresh start with FTD. Since FTD 6.5 is just out, and it enables the switchports on the FP1010, it was time to upgrade the appliance. In this post I will share my method of upgrading the FP1010 to the latest version, 6.5. 

Time to get started with the upgrade. In this blog post I assume the FP1010 appliance has never been booted and has just been unboxed. You need to have the following items

  • Laptop with FTP/SCP/SFTP server (TFTP is possible, I had issues with USB); I used my MacBookPro for this
  • Laptop connected to the management interface of the FP1010
  • The upgrade image, in my case: cisco-ftd-fp1k.6.5.0-115.SPA

Once you have everything ready, the following steps can be used to upgrade the FP1010 appliance:

Firepower architecture

Firepower appliances are really a different platform to the trusty old ASA platform. One of the architectural differences is that the appliance is running FXOS as the operating system and the security services you want to run (FTD or ASA) are installed as an instance. I think the best to compare it with is VMWare and running virtual services. FXOS looks a lot in its command set to the NFVIS operating system that runs on the ENCS series. It is based on the UCS platform and uses quite a different CLI then you are familiar with in the ASA world. 

The larger appliances (FP4100 and FP9300) FXOS and the security instances are separated, which means that you first configure FXOS and then you can load the security instance on it. The smaller Firepower appliances, such as the FP2100, FP1100 and the FP1000 series have FXOS and the security instance bundled in a single release. This means that you always run a specific FXOS system with a specific ASA or FTD version.

1.  Connect the console of the FP1010 to the laptop and power on the appliance
2.  Connect a network cable from the mgmt interface to your laptop

3.  Wait until the FP1010 is booted. Once it’s booted, the console will show:


4.  Type the command “connect ftd” and run through the initial setup wizard. If you do not accept the EULA and run through the setup, somehow the network is not working as expected and you cannot download the software. And yes, that took me some hours to figure out…

You must accept the EULA to continue.Press <ENTER> to display the EULA:
End User License Agreement

Effective: May 22, 2017

*** SNIP***
Please enter 'YES' or press  to AGREE to the EULA: YES

System initialization in progress.  Please stand by.
You must change the password for 'admin' to continue.
Enter new password:
Confirm new password:
You must configure the network to continue.
You must configure at least one of IPv4 or IPv6.
Do you want to configure IPv4? (y/n) [y]: y
Do you want to configure IPv6? (y/n) [n]: n
Configure IPv4 via DHCP or manually? (dhcp/manual) [manual]:
Enter an IPv4 address for the management interface []:
Enter an IPv4 netmask for the management interface []:
Enter the IPv4 default gateway for the management interface [data-interfaces]:
Enter a fully qualified hostname for this system [firepower]:
Enter a comma-separated list of DNS servers or 'none' [,]:
Enter a comma-separated list of search domains or 'none' []:
If your networking information has changed, you will need to reconnect.

Setting DNS servers:
No domain name specified to configure.
Setting hostname as firepower
DHCP server is enabled with pool: You may disable with configure network ipv4 dhcp-server-disable
Setting static IPv4: netmask: gateway: data on management0
Updating routing tables, please wait...
All configurations applied to the system. Took 3 Seconds.
Saving a copy of running network configuration to local disk.
For HTTP Proxy configuration, run 'configure network http-proxy'

Manage the device locally? (yes/no) [yes]: yes
Configuring firewall mode to routed

Update policy deployment information
    - add device configuration
Successfully performed firstboot initial configuration steps for Firepower Device Manager for Firepower Threat Defense.

5.  After the setup, the console will have a very empty prompt: “>” Now type exit The prompt will now look like firepower# 

6. This means you are now in FXOS , this looks like UCS CIMC software, so it is a bit different.
Enter the command scope firmware , the prompt will show

firepower /firmware
7. Check the IP address of your laptop and initiate the software download via the command structure

download image sftp://userid@iplaptop/path/to-image/cisco-ftd-fp1k.6.5.0-115.SPA

I have used

download image sftp://myuserid@

The console will now prompt for your password and then it will initiate a download task:

firepower /firmware # download image scp://myuserid@192.1687.45.46:/Users/myuserid/Downloads/cisco-ftd-fp1k.6.5.0-115.SPA
Please use the command 'show download-task' or 'show download-task detail' to check download progress.

You can use the “show download-task detail” to show the details, which has output like

Download task:
File Name: cisco-ftd-fp1k.6.5.0-115.SPA
Protocol: Sftp
Port: 0
Userid: myuserId
Path: /Users/myuserId/Downloads
Downloaded Image Size (KB): 59264
Time stamp: 2019-10-07T06:48:09.268
State: Downloading
Status: Downloading the image
Transfer Rate (KB/s): 29632.000000
Current Task: downloading image cisco-ftd-fp1k.6.5.0-115.SPA from 192.168.45

However, if there is a failure, it will only show “failed“. I found out that the command

show event provides much more information, but requires a bit decoding. The following output is from a successful download:
Creation Time            ID       Code     Description
------------------------ -------- -------- -----------
2019-10-07T06:48:09.269     27339 E4195702 [FSM:STAGE:END]: (FSM-STAGE:sam:dme:F
2019-10-07T06:48:09.269     27340 E4195703 [FSM:STAGE:END]: checking pending man
agement network config(FSM-STAGE:sam:dme:FirmwareDownloaderDownload:CheckPending
2019-10-07T06:48:09.269     27341 E4195704 [FSM:STAGE:ASYNC]: downloading image
cisco-ftd-fp1k.6.5.0-115.SPA from
But if there is a failure, it would look a bit more like this


2019-10-07T06:47:40.120     27329 E4195706 [FSM:STAGE:REMOTE-ERROR]: Result: end
-point-failed Code: ERR-DNLD-no-file Message: No such file#(sam:dme:FirmwareDown

It tells you it couldn’t find the file. The show event is quite handy.
Once the download is completed, the show detail command would look like this:

Download task:
    File Name: cisco-ftd-fp1k.6.5.0-115.SPA
    Protocol: Sftp
    Port: 0
    Userid: nefkensp
    Path: /Users/nefkensp/Downloads
    Downloaded Image Size (KB): 1031174
    Time stamp: 2019-10-07T06:48:09.268
    State: Downloading
    Status: validating and unpacking the image
    Transfer Rate (KB/s): 32224.187500
    Current Task: unpacking image cisco-ftd-fp1k.6.5.0-115.SPA on primary(FSM-ST

8.  Now that the software is downloaded, it is time to validate if the package is available. Use the command show package to check for that:

firepower /firmware # show package
Name Package-Vers
--------------------------------------------- ------------
cisco-ftd-fp1k.6.4.0-102.SPA 6.4.0-102
cisco-ftd-fp1k.6.5.0-115.SPA 6.5.0-115

9.  Now as the package is available, let’s install it. Go to the subscope auto-install:

firepower /firmware # scope auto-install
firepower /firmware/auto-install # 

10.  and install the package via the install security-pack version command:

firepower /firmware/auto-install # install security-pack version 6.5.0-115 
The system is currently installed with security software package 6.4.0-102, which has:
   - The platform version:
   - The CSP (ftd) version:
If you proceed with the upgrade 6.5.0-115, it will do the following:
   - upgrade to the new platform version
During the upgrade, the system will be reboot

Do you want to proceed ? (yes/no):yes

This operation upgrades firmware and software on Security Platform Components
Here is the checklist of things that are recommended before starting Auto-Install
(1) Review current critical/major faults
(2) Initiate a configuration backup

Do you want to proceed? (yes/no):yes

Triggered the install of software package version 6.5.0-115
Install started. This will take several minutes.
For monitoring the upgrade progress, please enter 'show' or 'show detail' command. 

11. Now let’s wait for the upgrade or use the “show” command to check the status:

firepower /firmware/auto-install # show

Firmware Auto-Install:
    Package-Vers Oper State                   Upgrade State
    ------------ ---------------------------- -------------
    6.5.0-115    Scheduled                    Ready
firepower /firmware/auto-install #

12.  And after waiting for some 20-30 minutes, FTD has been upgraded. Congratulations!

Cisco NL Strategic Innovation Tour 2019

Cisco NL Strategic Innovation Tour 2019

Fortunately, Cisco Netherlands organized another innovation tour for Cisco Partners in the week before Cisco Live US in San Diego. This time the innovation tour spanned two days and included visits to four tech companies in Sillicon Valley. In this blog I’d like to share my experiences of the tour.  

Apple Systems

Our first company visit was Apple Systems. And while many business visits happen at the 1 infinite loop building in Cupertino, we were honored to be invited to the new Apple Park campus building in Cupertino.

After a bit of a delayed start (well, Apple Park is huge!), we were welcomed by Apple in an environment quite beautiful .

There were a number of briefings, which were all very interesting. One was on how Apple is working with partners in its ecosystem, that not only includes Cisco on the networking side, but also a huge partnership with IBM on Swift and App developments. Another session was on how Apple sees the future, their role in the enterprise and they demo’ed several aspects of which were related to privacy, the announcements made at WWDC2019 earlier that week.

What really stood out for me was the way they demonstrated their new VoiceControl options for those that have disabilities. The video touched me, as I thought back to my father who died of A.L.S. in 2009, and how he might have used that (for a short period of time, as his speech deteriorated too). Besides this video, the capabilities of endpoint management that Apple can offer (both with and without supervised mode) were demonstrated, including a short briefing on the WWDC2019 announcement of having two distinct data-profiles on your iPhone. Of course, I already knew that a lot is possible for endpoint management on Apple devices, but the demo made clear that quite some nice new features have been introduced.

After the formal briefing sessions, we were invited to Apple’s visitor center, right across Apple Park. We got a tour through the visitor center, how it mirrors the new Apple Park Campus design and besides an awesome Augmented Reality app (see image below, thanks to Fred Spikker), the guide also explained how Apple park can already be so lush and green, while the building is only 2 years old! Steve Jobs and Jony Ive wanted to have employees working at Apple Park a full-grown experience, so they grew trees in other locations and moved them after the construction was finished!

But what really stood out to me was not the amazing design of the building itself, but the sustainability of the building. The building has zero CO2 footprint (even negative footprint, e.g. reducing) by large solar panels for power generation, but also the airflow of the cool San Francisco breeze is used to cool the building. They only need Airconditioning 3 months a year, the rest of the time, the wind is used for cooling. And yes, it was comfortable inside!


Our second visit on the first day was to Meraki HQ in San Francisco. And although we arrived late, we were welcomed at the Meraki office.

The session with Meraki and the tour around their office was interesting. Meraki still has a typical valley-startup vibe to it, which is acknowledged by the fact that personal packages can be delivered (or picked up) at the office, food provided by Meraki, dynamic office environments and not to forget, you can bring your dog along.

I don’t know what I can publicly share on the content of the sessions, but Meraki is really integrating more with Cisco Systems on several fields, such as integration with SDA and of course network programmability. Meraki of course already supported API’s, but they now have an API first strategy, so in time, everything you see in the web interface is effectively an API call to the backend. 

Cisco Systems

A visit to Cisco itself can of course not be forgotten. Day 2 started with a visit to Cisco’s Customer Experience Center in San Jose. And besides bumping into Chuck Robbins when walking through the center, we had some very interesting briefings.

The first briefing detailed the change that Cisco is foreseeing in the partnership. With Cisco profiling more as a software company, the partnership is changing. Don’t worry, Cisco still strongly believes and is committed to the partner model, but a different type of partners emerge besides just supplying the hardware boxes. It is part of the digital transformation and the journey a lot of organizations are on.

Image courtesy of Fred Spikker

The second briefing was very interesting. It was presented by Hugo Latapie, one of the experts on Artificial Intelligence and Machine Learning. What I truly loved about it is that he didn’t only demonstrate what can be done with deep fusion reasoning, but also the drawbacks on AI/ML. There are plenty of samples on the Internet where an image, used for learning, can be changed in such a way that a completely different object is recognized.


The last briefing was with Edwin Paalvast. As he is also Dutch, his briefing was in Dutch and he shared his vision on the challenges many enterprises face, and how Cisco can support them. And typical Dutch, we had a discussion on that vision and challenged one and another. I must say, I did recognise the problems he described and see them in my own environment too. And although the dot on the horizon is clear, the road to it is still a journey with a lot of hurdles to take in.


And well, we were at the customer experience center, so we also received a very nice demo on how Cisco’s security portfolio supports the enterprise and the world in a more secure environment.


The last company visit of this innovation tour was with Nvidia, in their brand new headquarters. What a beautiful building and what a difference with Meraki and the other companies too. 

NVidia welcomed us with a reference to an article that states that businesses in The Netherlands are, according to research, leading the way in applying Artificial Intelligence. And that not only the large corporations use them. 


After this quick intro, the four technology pillars of NVidia (Gaming, Professional Visualization, Artificial Intelligence, and Self-Driving Cars) were explained.


All these four pillars are driven by the same common technology, also known as GPU and how the innovation and evolution of the GPU have brought enormous computational power to different sectors.

The briefing also detailed on how AI has changed the world around us already, with AI driving suggestions within Search Engines, Image Recognition and other industrial fields. After a short explanation on the Cisco-NVIDIA partnership (where you can get these amazing GPU’s in an UCS appliance for VDI deployments or GPU-based machine learning), the power of GPU’s for AI were demonstrated along a number of verticals.

What I really liked about the story of Nvidia is their single platform strategy on GPU’s. Nvidia has a Deep Learning Institute that teaches organizations (and individuals) on how you use deep learning to solve complex problems. Everybody can take sessions within this institute and get started on GPU-based AI/Machine learning. And the single platform strategy means that you can start coding solutions yourself on a developer board, such as the Jetson Nano ($99) or Jetson TX2 (twice the power) and you can then scale that up to GPU-based cloud services or an on-prem solution without changing your code.
And yes, within the networking industry, we are only just getting started programming the network, imagine what you can do with your programming skills on these GPU’s. There is a whole new world out there. I bought one of these developer kits to see how I can use GPU computational power to solve networking problems…

After the briefing itself, we were showed around NVidia’s Customer Experience Center. In that center, they have demonstrations on all the things you can do with GPU’s, from image-learning at a much larger pace, to a visualized photo of a woman, which is not a real person (freaky), to the possibilities of creating a 3D cut of x-ray visions in the medical industry, or a short trailer of a completely computer-rendered movie, very realistic.


It is quite difficult to provide a summary of this year’s innovation tour. It was jam-packed and although each visited company is technology-focused, they have their own culture, vision, and strategy.

And throughout these differences, there is a thin red lining that touches all these companies, whether they are one of the thought leaders or applying them. And that is that technology is changing our lives in ways that we could not fathom five years ago. AI and ML are technologies that are here to stay, there are some drawbacks (like telling what is real and what is not, or that the quality of learning is poor, and some philosophical and social discussions that really need to take place). The general goal of this technology is for the good and to improve the quality of life. 

If I had to summarize the tour and things I saw and learned, I would use the following word.


(I really hope that 2020 will also have an Innovation Tour!)