OpenState: An Interface for Stateful Packet Processing in Programmable Switches

Quentin Monnet, 6WIND

IEEE Softwarization, March 2017

 

Is it possible to attain better performances and to create new use cases for SDN by moving some of the smartness from the controller to the programmable switches, while keeping an easy configuration interface? This article is a brief presentation of the OpenState abstraction layer [1] concept for stateful packet processing for programmable switching. This abstraction has been designed as part of the BEBA (BEhavioral BAsed switching) project [2], a European research effort funded by the Horizon 2020 program, and dedicated to improving performances through software acceleration as well as enhancing features of programming switches for SDN, by bringing back some of the logics from the controller into the switch using vendor-agnostic solutions.

Stateful packet processing

Concretely, the purpose is to provide the switches with stateful packet processing capabilities: when a packet arrives, it will not be processed solely according to the values contained it its headers (such as the protocol(s) in use, TCP/UDP ports, sender/receiver addresses etc.), but instead the switch will also take into account the packets that were previously received.

This is easier to understand with a simple example. Let's consider port knocking: this is a basic security method that consists in closing a (TCP|UDP) port on host, until a specific series of packets has been received from the sender. Imagine that the client foo, with IPv4 address 10.3.3.3, wants to connect to the server bar (10.1.1.1) through SSH (TCP port 22).

Figure 1

Figure 1: Simple network topology: the clients want to connect to the server through SSH.

The server bar can be directly reached on the Internet, and its administrator does not wish the TCP port 22 to look open to people performing port scans. So, they have enabled port knocking: to open the port to a client, foo for instance, the server must receive from this client a specific sequence of “knocks”. In this example, server bar waits for UDP packets on ports 1111, 2222, 3333, then TCP port 4444, in this order. Once this sequence of packets has been received from a host, the server opens its TCP port 22 for this host, and the SSH connection becomes possible. The graphical representation of this operation, in the shape of a state machine, is represented on the figure below.

Figure 2

Figure 2: Port knocking state machine

Could we replicate this mechanism inside a switch? All TCP packets from foo and addressed to bar should be discarded, until foo provides the correct UDP packets secret sequence. To recognize the sequence of packets, the switch has to keep in memory the information related to previously received packets belonging to this sequence. In other words, it must implement the state machine associated to port knocking. This is exactly what OpenState permits to do.

OpenState

On a classic SDN network, the switch can identify the packets that are part of the secret sequence, but it cannot tell if this sequence is being executed in the correct order. All those packets would be sent back and forth to the controller, wasting time and resources.

Instead, OpenState brings stateful processing of packets, by proposing an implementation of simplified “eXtended Finite State Machines” (XFSM), also known as Mealy machines [3]. A Mealy machine is an abstract structure comprising a 5-tuple:

  • A finite set of states.
  • An initial starting state, DEFAULT in the example.
  • A finite set of input symbols: the events to match with the packet, such as “TCP dst port = 22”.
  • A finite set of output symbols: the actions (“drop”, “forward”, “push/pop a header”, “create a new flow rule” etc.
  • A transition function mapping (state, event) pairs into (state, action) pairs.

Concretely, say I am a switch proposing port knocking features: if I am in state STEP_3 and I receive a TCP packet on port 22, I go to a new state, OPEN, and I perform an action: I forward the packet to its recipient. If, on the contrary, I receive any other packet, or if the timeout fires, then the new state will be the initial state, and the action consists in dropping the packet.

How do these machines get integrated to the data plane? The OpenState abstraction layer is implemented by means of two new tables, that replace the former flow table.

The first of those tables is the “state table”.

To each flow pattern, it associates a state key instead of a direct action. The second one is called the “XFSM table”, and to a state and an “event”, it associates an action (to apply to the packet) as well as a new state. OpenState describes the following flow of table manipulations:

  1. A first step consists in realizing a “state table lookup”. This implies that as a necessary sub-step, the packet is processed by a “key-extractor” that produces a string of bits, which is used as a key to match a row in the state table. The fields taken into account for the creation of this key are the header fields described in what is called the “lookup-scope”. So, once we have the key, we search the state table: this lookup returns the current state for the flow the packet belongs to.
  2. For the second step, this returned state is appended to the key, and a second lookup is performed, this time in the XFSM table. It matches both on the state and on the packet metadata, and returns an action indicating what to do with the packet, as well as a new state.
  3. The final step consists in updating the state table with the new value. To do so, the key is processed by another key extractor, the “update scope”. At the end of this process, the table contains the new state for the flow.

Not counted in the three steps is also the execution of the action returned by the XFSM table, that is used to actually process the packet.

Let’s see now what it gives with the port knocking example:

  • SSH from 10.1.1.1 is allowed.
  • SSH from 10.2.2.2 to 10.1.1.1 is allowed.
  • SSH from 10.3.3.3 to 10.1.1.1 is initially forbidden, but can be allowed after the client at 10.3.3.3 sends the correct sequence.

In this setup, at a given time, the traffic from each host is in one of the following states:

  • DEFAULT: no SSH allowed.
  • OPEN: SSH traffic (TCP towards port 22) is allowed.
  • STEP_1; or STEP_2, or STEP_3: the port knocking sequence is ongoing.

For 10.1.1.1 and 10.2.2.2, the state is always OPEN. But for 10.3.3.3, it depends on the progress of the secret sequence, so the state may evolve. Thus, the state table itself can evolve, without the intervention of the controller: the switch tracks the succession of states.

For instance, assuming that 10.3.3.3 has sent the first packet of the sequence (UDP on destination port 1111), the switch starts with the first step: state table lookup. The state table is as follows (when searching for a match, the tables that are provided here are scanned from top to bottom, so the packets not matching any other pattern will be assigned the DEFAULT state by the last flow pattern):

Figure 3

Figure 3: State table, when in DEFAULT state.

But how exactly are these states expected to evolve? All the next possible steps are in the XFSM table. So the switch carries on to the second step, and performs an XFSM table lookup. This table, depicted below, has two main blocks: “Flow matching pattern” and “Actions”.

The former is subdivided into two columns: “State” and “Event”. The matching row is the one for which the first (State) column is matched by the current flow state (e.g. STEP_1) and the second (Event) column is matched by the packet (e.g. TCP dst port = 2222).

The second block of columns gathers two columns, “Action” and “Next state”. Once the matching row has been determined with the state and events associated to the packet, the corresponding action, found in the third column, is applied (e.g. Drop).

Here is the XFSM table coming with our example port knocking use case:

Figure 4

Figure 4: XFSM table.

At last, the state table update occurs. The state for the flow of the packet is modified, as indicated by the state name found in the Next state column.

Let’s connect the three steps: if the first packet of the sequence has been previously received (the state is STEP_1), and a new packet from host 10.3.3.3 is received, the State table is scanned first. The third row from the top is hit. It returns state STEP_1, and this information is used to search the second table. Two cases:

  1. The event on row 2 is matched: the packet is a TCP packet, with destination port = 22.
  2. The packet is anything else, and the very last row is matched instead.

If the packet received is not a TCP packet towards port 22 (second case) then the packet is dropped, and the state is moved to DEFAULT. As a consequence, the port knocking sequence is “reset”.

If, on the contrary, the packet targets TCP port 22, the packet is dropped all the same, but the state for this flow—the flow of packets sent from 10.3.3.3 to 10.1.1.1—is changed to STEP_2. This means that the State table is modified, and now looks like this:

Figure 5

Figure 5: State table, when in STEP_1 state.

The next packet from 10.3.3.3 will match the third row again, but this time it will return STEP_2, so the switch will look for a different row in the XFSM table. If again a new packet from the port knocking sequence is received, the state will move to STEP_3, and ultimately to OPEN.

Leveraging OpenState

These were the main lines of OpenState. With a similar setup, it is possible to implement many applications relying on stateful processing, including load balancing, failure detection and recovery, in-switch ARP handling, middlebox or distributed protection against DDoS, and others [5 (D5.1, D5.2)]. BEBA research project heavily relies on this concept, and goes further. Some related items include:

  • Hardware proof of concept of OpenState abstraction layer [4].
  • OpenState can be extended with per-flow registries and conditions. This is called Open Packet Processor [5 (D2.3)].
  • Software acceleration of switches running the OpenState layer [5 (D3.3)].
  • Development of a reference implementation of the interface (switch and controller) [6].

Regarding the BEBA project as a whole, it entered its final phase. This is the interesting part, with results coming from different sizes:

  • The performance tests are providing the first results. While the final benchmarks are not finished at this time, we know that the software acceleration effort performed on the reference implementation (based on ofsoftswitch, and accelerated with the PFQ framework) runs at nearly 90 times its initial speed.
  • OpenState is envisioned to be integrated into industrial products, although no public announcement has been made this far.
  • Regarding standardization, OpenState is being pushed as an OpenFlow extension at the ONF. The proposal is actually undergoing some changes to address minor issues.

Hopefully, it will help deploy a variety of stateful applications for even faster SDNs!

 

References

  • [1] OpenState: G. Bianchi, M. Bonola, A. Capone, and C. Cascone, “OpenState: Programming Platform-independent Stateful OpenFlow Applications Inside the Switch” ACM SIGCOMM Computer Communication Review, vol. 44, no. 2, pp. 44–51, 2014 (link).
  • [2] BEBA project web page.
  • [3] Mealy machines: definition on Wikipedia.
  • [4] Hardware implementation: S. Pontarelli, M. Bonola, G. Bianchi, A. Capone, C. Cascone, “Stateful Openflow: Hardware Proof of Concept”, IEEE HPSR 2015, Budapest, July 1−4, 2015 (link).
  • [5] BEBA's list of public deliverables (link). In particular, deliverables D2.1 and D2.2 relate to the design and basic implementation of the OpenState layer.
  • [6] Reference implementation of BEBA switch, on GitHub.

 


 

Quentin Monnet joined 6WIND as a R&D Engineer in 2015, and works on high performance networking software. Just before that, he defended his PhD thesis about security against DoS in sensor networks at “Université Paris-Est”, France. He is involved in European research projects about fast and flexible packet processing, and has been modestly contributing to several open-source projects.

 

Editor:

Marie-Paule OdiniMarie-Paule Odini holds a master's degree in electrical engineering from Utah State University. Her experience in telecom experience including voice and data. After managing the HP worldwide VoIP program, HP wireless LAN program and HP Service Delivery program, she is now HP CMS CTO for EMEA and also a Distinguished Technologist, NFV, SDN at Hewlett-Packard. Since joining HP in 1987, Odini has held positions in technical consulting, sales development and marketing within different HP organizations in France and the U.S. All of her roles have focused on networking or the service provider business, either in solutions for the network infrastructure or for the operation.

 


 

Subscribe to IEEE Softwarization

Join our free SDN Technical Community and receive IEEE Softwarization.

Subscribe Now

 


Article Contributions Welcomed

Download IEEE Softwarization Editorial Guidelines for Authors (PDF, 122 KB)

If you wish to have an article considered for publication, please contact the Managing Editor at sdn-editor@ieee.org.

 


Past Issues

November 2018

March 2018

January 2018

December 2017

September 2017

July 2017

May 2017

March 2017

January 2017

November 2016

September 2016

July 2016

May 2016

March 2016

January 2016

November 2015


IEEE Softwarization Editorial Board

Laurent Ciavaglia, Editor-in-Chief
Mohamed Faten Zhani, Managing Editor
TBD, Deputy Managing Editor
Syed Hassan Ahmed
Dr. J. Amudhavel
Francesco Benedetto
Korhan Cengiz
Noel Crespi
Neil Davies
Eliezer Dekel
Eileen Healy
Chris Hrivnak
Atta ur Rehman Khan
Marie-Paule Odini
Shashikant Patil
Kostas Pentikousis
Luca Prete
Muhammad Maaz Rehan
Mubashir Rehmani
Stefano Salsano
Elio Salvadori
Nadir Shah
Alexandros Stavdas
Jose Verger