Thursday, December 15, 2016

NFV'ing LLDP (making IP phones work)

Many IP phones use LLDP to figure out what VLAN to use, for DHCP (having a built in switch - the phone accepts both tagged and untagged traffic - the untagged traffic is switched through to a connected device like a PC, and the tagged traffic the phone keeps to itself).

The phone generally waits for an LLDP server to send it an LLDP frame to cue it with the right VLAN to use. FAUCET doesn't do LLDP itself, but, it does of course support doing via NFV. Simply run lldpd on your NFV host, and configure the NFV interface to be in the same untagged (native) VLAN as the port with the phone (the phone's interface will have both tagged and native configuration).

You will also have to specify "drop_lldp: False" in the datapath section of FAUCET's config, to tell FAUCET not to drop LLDP by default.

lldpd should have configuration like (to quote the man page -

configure med policy application voice vlan 500 priority voice dscp 46

For an extra level of rigor, you could configure a FAUCET ACL that ensures LLDP from client ports is unconditionally forwarded to the NFV host (so that no other connected device could potentially spoof LLDP).

Monday, November 28, 2016

FAUCET tutorials at NZNOG 2017

Run by two of the core FAUCET development team.

FAUCET supports Netronome adaptors

Netronome produce PCIe adaptors, with an OVS interface (

The following shows an Agilio CX 2x10GbE card controlled by FAUCET. As you can see, because the interface to the card is just OVS, FAUCET works exactly the same way as if it were controlling an OVS software-only switch.

root@faucet:~# cat /etc/ryu/faucet/faucet.yaml 
version: 2
        name: "test"
        dp_id: 0x154d122298
        hardware: "Netronome"
                native_vlan: 100
                native_vlan: 100
root@faucet:~# ovs-ofctl -OOpenFlow13 dump-ports br0
OFPST_PORT reply (OF1.3) (xid=0x2): 3 ports
  port LOCAL: rx pkts=0, bytes=0, drop=0, errs=0, frame=0, over=0, crc=0
           tx pkts=0, bytes=0, drop=0, errs=0, coll=0
  port  1: rx pkts=14277135, bytes=1056790647, drop=2, errs=0, frame=0, over=0, crc=0
           tx pkts=14338267, bytes=1061587014, drop=0, errs=0, coll=0
  port  2: rx pkts=14338260, bytes=1061586428, drop=2, errs=0, frame=0, over=0, crc=0
           tx pkts=14277141, bytes=1056790806, drop=0, errs=0, coll=0
root@faucet:~# ovs-vsctl show 
    Bridge "br0"
        Controller "tcp:"
            is_connected: true
        fail_mode: secure
        Port "sdn_p1"
            Interface "sdn_p1"
        Port "sdn_p0"
            Interface "sdn_p0"
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.5.1"

Tuesday, November 8, 2016

FAUCET article on ACM Queue

Faucet: Deploying SDN in the Enterprise

Using OpenFlow and DevOps for rapid development

Josh Bailey and Stephen Stuart

The 2008 publication of "OpenFlow: Enabling Innovation in Campus Networks" introduced the idea that networks (originally campus and enterprise networks) can be treated more like flexible software rather than inflexible infrastructure, allowing new network services and bug fixes to be rapidly and safely deployed.7
Since then many have shared their experiences using SDN (software-defined networking) and OpenFlow in wide area and data center networks, including at Google.10 This article returns to enterprise and campus networks, presenting an open-source SDN controller for such networks: Faucet. The Faucet controller provides a "drop-in" replacement for one of the most basic network elements—a switch—and was created to easily bring the benefits of SDN to today's typical enterprise network.5

Friday, November 4, 2016

OpenFlow: not dead yet

I can’t tell you exactly where Guru and I were this week, but we were visiting one of our hyperscale member companies, talking about open source software. It was really exciting to see that some of the work we have been doing is actually being leveraged by “the big guys.” While we were talking about plugfests and programs and operations and development plans and communities and all the tools and structures to support dynamic open source projects, our host leaned over and looked at Guru and me as the conversation paused. Guru asked, “What can ONF do for your organization?”, and there was a thoughtful pause.

“Tell everyone . . . OpenFlow is not dead,” were his words, carefully delivered, as if he had been rehearsing them for some time. “Take due care of OpenFlow”, he seemed to say, as if there was some risk that in the hurtling rush to “The Next Big Thing”, we might accidentally divert our attention from some of the core plumbing in the SDN ecosystem.

Wednesday, October 26, 2016

FAUCET users list

G√ČANT have kindly set up a new email list for FAUCET users:

Monday, October 24, 2016

FAUCET V1.2 released

FAUCET V1.2 has just been released, with some important bugfixes when using the version 2 config format (and if you haven't already migrated from v1, you should migrate now as v1 is no longer supported).

FAUCET V1.2 also includes experimental distributed switching support (distributed switching will continue to develop further).

Thursday, October 20, 2016

Experimental stacking and distributed switching support

FAUCET can now do - experimentally - distributed switching.

This means that you can connect a bunch of FAUCET switches together, in an arbitrarily complex topology, and FAUCET will make them behave like one switch.

Many non-SDN switches support "stacking", which uses (usually) proprietary cables to achieve the same end. In FAUCET, they are just Ethernet connections. We administratively declare which connection goes where, and we nominate a switch to be at the root of the topology (by giving it a priority of 1 - in the future we will support more complex ideas).

In this version, distributed switching is very simple - all switches are programmed using an SPF algorithm. There is no need for a spanning tree protocol, because the controller has global visibility and complete control over all the switches. There is no load balancing implemented (yet) and we rely on Ethernet link status for failure detection at the edges (and only at the edges).

However, because FAUCET is open source, we can easily add other algorithms - for example to load balance based on Ethernet destination address. We can also be more clever about link failure detection (for example, we can inject test traffic to detect when a link has been configured on the wrong port).

The following configuration is for the simplest possible layout (two switches, one link).

        name: "avlan"
        dp_id: 0x1
        hardware: 'Open vSwitch'
            priority: 1
                native_vlan: 100
                native_vlan: 100
                native_vlan: 100
                     dp: f2
                     port: 4
        dp_id: 0x2
        hardware: 'Open vSwitch'
                native_vlan: 100
                native_vlan: 100
                native_vlan: 100
                     dp: f1
                     port: 4

Thursday, October 13, 2016

Running FAUCET as a systemd controlled service in Ubuntu 16

Ubuntu 16 pushes us towards systemd ( to manage services. In a recent installation I used this process to have FAUCET run as a service and have it automatically start on boot. 

There's more than one way to do this (in particular, you can systemd to directly start FAUCET as the correct user, rather than via sudo). We're also working on making this easier.

1. Create a user to run FAUCET as. On my system, I created a user "faucet". 

# useradd faucet

2. Install FAUCET itself. You have a few choices - here are two (pip is the easiest; the git clone will get you the latest development version).
  • pip
# pip install ryu-faucet
  • git
# cd /home/faucet/
# git clone

3. Identify the root of the FAUCET installation is in your installation. 

# find / -name

In my case, it's /home/faucet/faucet

4. Create a file,/etc/default/faucet,  containing the following. Substitute in the correct values for your FAUCET installation path, and where you want your config files and logs. Don't forget that the log files will need to be writable by the faucet user, so make sure there's a directory faucet can write to.

# path to Ryu manager (likely local)
# user to run FAUCET as (must already exist)
# directory containing FAUCET application code
# file containing Gauge's custom ryu.conf
# host address FAUCET controller should listen on for OpenFlow switch
# TCP port FAUCET controller should listen on for OpenFlow switch
# location of FAUCET's configuration file.
# where FAUCET should log to (directory must exist and be writable by FAUCET_USER)
# where FAUCET should log exceptions to (directory must exist as above)

5. Create another file, /home/faucet/, that will start FAUCET (and don't forget to make it executable):

sudo -E -u $FAUCET_USER $RYU_MANAGER --config-file=$FAUCET_RYU_CONF --ofp-listen-host=$FAUCET_LISTEN_HOST --ofp-tcp-listen-port=$FAUCET_LISTEN_PORT $FAUCET_APP_DIR/

6. Create the last file, /etc/systemd/system/faucet.service that defines the FAUCET service:

description="FAUCET OpenFlow switch controller"



7. Enable the systemd-networkd-wait-online.service service. This has systemd wait for the network to come up, before trying to start FAUCET:

# systemctl enable systemd-networkd-wait-online.service

8. Enable the FAUCET service you just created:

# systemctl enable faucet

9. Start FAUCET and view its status:

# systemctl start faucet
# systemctl status faucet

Friday, September 16, 2016

Include files

FAUCET allows you to split your config into separate files, so that automated generation/replacement of files is easier (E.g., if you want to change the configuration of a single ACL, you can replace just that file rather than having to merge your change into one file).

For an example, see Specifically:

# test include
- testconfigv2-dps.yaml
# test include-optional
- testconfigv2-acls.yaml

The first file will be read and included (and it must be present). 

The second file will be read and included, if present.

Where's the northbound API?

(For background, see

When speaking about SDN, a northbound API is something used to tell an SDN controller (versus an SDN controlled device) to do something. For example, you might use it to tell an SDN controller to prioritize a certain user's traffic over other traffic. It's up to the SDN controller to instruct devices in turn to do implement your request (generally with a southbound API, like OpenFlow).

FAUCET doesn't have a northbound API as such, because it doesn't need one. Instead, you can just change FAUCET's config file and HUP the FAUCET to have the change take effect. As an example, see - we combine NFV (of authentication) with a triggered update of FAUCET's config file (to remove an ACL from a port once a user has been authenticated).

In summary. If you want to orchestrate a fleet of FAUCET based switches, change user VLANs on the fly, update ACLs, override forwarding with policy based forwarding (Eg,, etc, then you would script generation of new FAUCET configs as appropriate and signal FAUCET to apply the change.

Tuesday, September 13, 2016

ODBC support (flows and stats logging to external database)

FAUCET's monitoring application, Gauge, can now push flow table changes and port based statistics to ODBC databases (including CouchDB). This means that monitoring and security applications are much easier to develop, because they don't need to directly interact with OpenFlow switches, and since FAUCET can push statistics there is no need for a database to poll each switch or FAUCET instance.

You can find an overview of how this is configured at

Friday, September 2, 2016


FAUCET version 1.1 has been released:

This release consolidates and introduces:

  • further progress on automated testing (including automated testing of hardware)
  • new configuration format and support for a single FAUCET controller handling multiple datapaths
  • policy based forwarding (ACLs can override and/or augment standard forwarding behavior).
  • BGP routing
  • Configuration of OpenFlow pipelines with the standard "table features" mechanism.

Monday, August 29, 2016

FAUCET on docker

docker allows you to precisely describe what an application needs, and also isolate it from what it shouldn't need. This makes installation and testing much easier. In FAUCET's case, WAND have done a nice job - as well as packaging installation, they have packaged tests. Running FAUCET's unit tests is now very easy (see below). See also for how to use docker to install and upgrade FAUCET itself.


This runs the mininet tests from the docker entry-point:
docker build -t reannz/faucet-tests -f Dockerfile.tests .
apparmor_parser -R /etc/apparmor.d/usr.sbin.tcpdump
modprobe openvswitch
sudo docker run --privileged -ti reannz/faucet-tests

Thursday, August 18, 2016

SimpleSwitch 2

SimpleSwitch Reimagined is heavily influenced byFaucet, an Open Source commercial-grade OpenFlow controller application for Ryu. Our purpose was not to rewrite Faucet, but to write an easy-to-understand controller application for learning more advanced OpenFlow concepts. As a result, SS2 does not include some of Faucet’s features such as VLAN learning, but is written to be very easy to follow and and to teach useful design patterns for Ryu controller applications and OpenFlow in general. This tutorial will run through the core of SS2, explaining the thinking and design behind every bit of code and hopefully provide you with ideas on writing your own controller application. The structure and concepts employed by SS2 will also help introduce the logic behind Faucet when we explore it in the near future.

Tuesday, August 9, 2016

FAUCET now supports multiple switches/datapaths

FAUCET now supports the configuration and control of multiple switches, via the same FAUCET process.

Here is a configuration extract for FAUCET controlling two switches at once (Allied Telesis and Zodiac FX).

version: 2
        name: "clock"
        unicast_flood: False
        max_hosts: 3
        name: "trusted network"
        unicast_flood: true 
        max_hosts: 20
        name: "untrusted network"
        unicast_flood: False 
        max_hosts: 20
        name: "roof network"
        unicast_flood: True
        max_hosts: 10
        - rule:
            dl_src: "ae:ad:61:7d:02:2f"
                allow: 1 
        - rule:
                allow: 0
        dp_id: 0x70b3d56cd0c0
        hardware: "Open vSwitch"
                native_vlan: 100 
                name: "clock"
                native_vlan: 100
                name: "VLAN 2001"
                acl_in: 100
        dp_id: 0x0000eccd6df72de7
        description: "Josh's experimental AT-X930"   
        hardware: "Allied-Telesis" 
                tagged_vlans: [2001,2002,2003]
                name: "port1.0.1"
                description: "windscale"
                native_vlan: 2001
                name: "port1.0.2"

                description: "vek-x"

FAUCET deployments

Here is a map, that we will keep updated with sites that have deployed FAUCET (and don't mind saying so!).

Sunday, August 7, 2016

New configuration format (better Gauge, and enabling multiple datapaths)

FAUCET's original author, Chris Lorier has significantly improved FAUCET configuration.

In particular, it's now possible for you to do things like configure InfluxDb's credentials or even have multiple different kinds of polling/data logging.

You can also configure multiple datapaths (switches) in the same config file - a forthcoming feature will enable one FAUCET process to control many switches.

Read more about the changes here:

In summary, each switch now as a stanza under "dps", and "interfaces" moves under each datapath's configuration. VLAN configuration is shared among datapaths for the moment.

It is strongly recommended you update your configuration to the new format as soon as possible, as the old format is deprecated and will be removed shortly.

Sunday, July 31, 2016

Automatically documenting/generating OF pipelines

FAUCET now has code that automatically enforces correct documentation, of what OpenFlow matches are used in what table. Today, it looks like this (see end of this post).

This is very useful, because it enables you to correctly configure hardware that needs to know what matches are used in what table, in advance. It also lets you optimize the pipeline (for example, by removing matches from tables that don't need them, which can increase forwarding performance).

FAUCET could also support a P4 switch running an OF bridge, if that bridge supported these matches in these tables.

FAUCET's pipeline could use some further optimization (particularly of eth_src_table, which is quite "wide" - it could match a lot of things). This is ongoing.

        self.TABLE_MATCH_TYPES = {
            self.dp.vlan_table: (
                'in_port', 'vlan_vid', 'eth_src', 'eth_dst', 'eth_type'),
            # TODO: eth_src_table matches too many things. It should
            # be split further into two tables for IPv4/IPv6 entries.
            self.dp.eth_src_table: (
                'in_port', 'vlan_vid', 'eth_src', 'eth_dst', 'eth_type',
                'icmpv6_type', 'ipv6_nd_target',
                'arp_tpa', 'ipv4_src'),
            self.dp.ipv4_fib_table: (
                'vlan_vid', 'eth_type', 'ip_proto',
                'ipv4_src', 'ipv4_dst'),
            self.dp.ipv6_fib_table: (
                'vlan_vid', 'eth_type', 'ip_proto',
                'icmpv6_type', 'ipv6_dst'),
            self.dp.eth_dst_table: (
                'vlan_vid', 'eth_dst'),
            self.dp.flood_table: (
                'vlan_vid', 'eth_dst'),

Monday, July 18, 2016

Policy based forwarding with FAUCET

Sometimes, you want certain traffic to be taken out of the dataplane, and entirely diverted to another system (for example, you want to redirect all DHCP request broadcasts to only one DHCP server, or you want a DDoS system to perform deeper analysis).

FAUCET allows you to configure an ACL to divert any packet that can be matched by OpenFlow, to a port, and optionally have the destination address rewritten.

        - rule:
            dl_dst: "01:02:03:04:05:06"
                    dl_dst: "06:06:06:06:06:06"
                    port: 2

In this example, any traffic with an Ethernet destination of 01:02:03:04:05:06, will be intercepted, will have its destination address rewritten to be 06:06:06:06:06:06, and then output port 2.

The match expression can match anything OpenFlow can; for example, you could match source or destination IP address.

Here's another example that matches DHCP requests and redirects them to port 1:

        - rule:
            dl_dst: "ff:ff:ff:ff:ff:ff"
            dl_type: 0x800
            nw_proto: 17
            nw_src: ""
            nw_dst: ""
            tp_src: 68
            tp_dst: 67
                    port: 1

And output from an Allied Telesis switch that shows it working:

awplus#show openflow rules |include table_id=1
table_id=1, duration=69s, n_packets=1, n_bytes=377, priority=9099,udp,in_port=23,dl_dst=ff:ff:ff:ff:ff:ff,nw
table_id=1, duration=69s, n_packets=8590, n_bytes=11026081, priority=9098,in_port=23,actions=goto_table:2
table_id=1, duration=69s, n_packets=0, n_bytes=0, priority=0,actions=drop

Routing protocol offload with FAUCET (FAUCET does BGP)

As with protocols like 802.1x, it is possible to offload routing protocols with FAUCET.

FAUCET now speaks basic BGP (it can both advertise its own IPv4 and IPv6 routes, and it can learn BGP routes). This this is sufficient to communicate with a more sophisticated route processor, like Quagga or BIRD - the external processor does the filtering and processing of community strings, etc - and exports the resulting RIB to FAUCET, which simply uses it for a FIB.

This implies further that FAUCET can now effectively speak any routing protocol that the external routing processor can speak, because the external processor has only to translate to simple BGP. 

Since FAUCET can do IPv4 and IPv6 routing in the dataplane itself, including nexthop resolution, dynamic routing can be done by the controlled OpenFlow switch. 

Tuesday, July 12, 2016

802.1x authentication on FAUCET (NFV offload of authentication).

In this post, we will discuss how to add 802.1x to any FAUCET controlled switch. This is a good example of how SDN can add functionality to a switch with just a controller upgrade - no changes to the dataplane are required.

802.1x is a standard for network authentication - whether a given device should be allowed access to the network (whether WiFi or wired).

Here's an overview of how it works with FAUCET.

  • A host, connected to the Ethernet switch, sends 802.1x authentication request packets to the switch. The switch passes them on to the controller/NFV's offload port.
  • A process, hostapd receives these packets and facilitates an authentication conversation with a RADIUS server (see here for an extremely detailed explanation).
  • Whether successful or unsuccessful, hostapd notifies another process on the same host, hostapd_cli.
  • A script, (see below) monitors hostapd_cli, and the FAUCET controller's log file. It correlates the MAC address of the host with the port the host is connected to on the switch, and then initiates the desired action (for example, opening a firewall port so the host can access the Internet - if successfully authenticated).

This implementation is a proof of concept of implementing the authentication entirely within the dataplane. The FAUCET controller does not participate or understand the 802.1x exchange and does not need to. Other services, like DNS and DHCP could also be run on the same host, in the same way. The trigger script can perform any action, including, modifying the FAUCET config file itself and HUPing the controller (for example, to add or remove an OpenFlow ACL to the host's port to authorize it to access the network).

For a more advanced solution including an administrative GUI, a system like PacketFence could be integrated. For example, PacketFence could also change FAUCET's config to put a problematic host in a quarantine VLAN.

There are some features being added to FAUCET to support better integration. For example, this proof of concept uses the FAUCET log file, but FAUCET will expose what it knows programmatically (specifically, what MAC addresses have been learned on what ports). There are also features to force all 802.1x, etc traffic to the offload port only, and more efficiently add or remove an ACL/VLAN from a port when requested.

hostapd takes a minimal configuration file, instructing it to listen on a port, communicate with a RADIUS server, and notify an external process of events:



In this case it will listen on eth0.2001, which is a tagged port for FAUCET VLAN 2001. We will use a RADIUS server running on the same host as the controller (how to configure the RADIUS server can found above).

The trigger script follows. While a proof of concept it demonstrates how to correlate the host's MAC with a port and then call an external system (future versions of FAUCET will support proper programmatic access, as above).


import fcntl
import os
import re
import subprocess
import time

PORTS = [5]
mac_to_port = {}
mac_authenticated = {}

faucet_log = open('/var/log/faucet/faucet.log')
fcntl.fcntl(faucet_log.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
hostapd_cli = subprocess.Popen(
    ['/usr/local/sbin/hostapd_cli', '-p', '/var/run/hostapd'],
fcntl.fcntl(hostapd_cli.stdout, fcntl.F_SETFL, os.O_NONBLOCK)

while True:
   log = faucet_log.readline()
   hostapi_log = ''
       hostapi_log = hostapd_cli.stdout.readline()
   except IOError:
   status_change = False
   # did we learn a MAC on a port?
   if log:
       m ='src:(\S+) in_port:(\S+)', log)
       if m:
           mac =
           in_port = int(
           if in_port in PORTS:
               if mac not in mac_to_port or mac_to_port[mac] != in_port:
                   mac_to_port[mac] = in_port
                   print 'mac %s is on port %u' % (mac, in_port)
                   status_change = True
       if not status_change:
   # was a MAC authenticated or de-authenticated
   if hostapi_log:
       connected_m ='AP-STA-CONNECTED (\S+)', hostapi_log)
       disconnected_m ='AP-STA-DISCONNECTED (\S+)', hostapi_log)
       if connected_m:
           mac =
           mac_authenticated[mac] = True
           print 'mac %s authenticated' % mac
           status_change = True
       elif disconnected_m:
           mac =
           mac_authenticated[mac] = False
           print 'mac %s not authenticated' % mac
           status_change = True
   if status_change:
       for mac, in_port in mac_to_port.iteritems():
           print mac, in_port,
           if mac in mac_authenticated:
               print mac_authenticated[mac]
               print 'unknown'

Sunday, June 26, 2016

Monitoring FAUCET with Grafana and InfluxDB

Instead of SNMP, FAUCET can push basic statistics - port input and output bytes and packets - to InfluxDB. You can then graph them using Grafana. In this post we will discuss how to set up FAUCET to do this.


  • We will indeed to install InfluxDB and Grafana on the same machine that runs FAUCET (it is possible to run them on different machines or across a network also, but this is the most simple configuration).
InfluxDB (
Grafana (
  • Create an InfluxDB database for FAUCET to populate:

$ influx
Visit to register for updates, InfluxDB server management, and monitoring.
Connected to http://localhost:8086 version 0.13.0
InfluxDB shell version: 0.13.0
> create database faucet

  • Now to configure FAUCET monitoring FAUCET has a separate script, gauge, that does monitoring (monitoring therefore is completely separate from switching). gauge uses FAUCET's config file, and one of its own, gauge.yaml:
    - '/etc/ryu/faucet/faucet.yaml'
        type: 'port_stats'
        dps: ['windscale-faucet-1']
        interval: 10
        db: 'influx'
        type: 'influx'
        influx_db: 'faucet'
        influx_host: 'localhost'
        influx_port: 8086
        influx_user: 'faucet'
        influx_pwd: ''

        influx_timeout: 10

  • Next, you will need to configure the switch to connect to gauge. gauge is, from the switch's point of view, an additional OpenFlow controller, that only requests statistics via OpenFlow. Add the necessary configuration to the switch to connect to a port on the machine where gauge will run (Eg, 6634). 

  • Next, run gauge. Eg,

/usr/bin/python /usr/local/bin/ryu-manager --ofp-listen-host=[controller IP] --ofp-tcp-listen-port=6634 /home/faucet/faucet/src/ryu_faucet/org/onfsdn/faucet/
  • You should now start to see gauge start to poll for statistics once the switch has connected. Check /var/log/faucet/gauge.log (default log location).
  • Now check that InfluxDB is receiving the data. 

$ influx
Visit to register for updates, InfluxDB server management, and monitoring.
Connected to http://localhost:8086 version 0.13.0
InfluxDB shell version: 0.13.0
> use faucet
Using database faucet
> show measurements
name: measurements
> show series
  • It should now be possible for you to graph FAUCET data from the Grafana UI.