Software-Defined Networking (SDN) separates the control plane from the data plane, giving you centralized, programmable control over your entire network infrastructure. Instead of configuring each switch individually, an SDN controller manages flow rules across all devices from a single point.

In this guide, we compare three leading open-source SDN controllers — OpenDaylight, Faucet, and Ryu — covering architecture, features, deployment, and real-world use cases. Whether you are building a campus network, a cloud data center, or a home lab, this comparison will help you choose the right controller.

Why Self-Host Your SDN Controller

Running your own SDN controller gives you full control over network policies, visibility, and automation. Commercial SDN solutions often come with licensing costs, vendor lock-in, and limited customization. By self-hosting an open-source controller, you get:

  • Full control over routing policies, ACLs, and QoS rules
  • No vendor lock-in — OpenFlow is an industry standard supported by most enterprise switches
  • Cost savings — no per-port or per-switch licensing fees
  • Automation-ready — programmable APIs enable integration with orchestration tools like Ansible and Terraform
  • Deep visibility — centralized telemetry and flow-level monitoring across your entire network

For organizations managing complex network topologies, a self-hosted SDN controller is the foundation of infrastructure-as-code for networking.

OpenDaylight: Enterprise-Grade SDN Platform

OpenDaylight (ODL) is a Linux Foundation project and one of the most comprehensive SDN platforms available. It provides a modular, plugin-based architecture that supports multiple southbound protocols beyond OpenFlow, including NETCONF, BGP-LS, and PCEP.

  • GitHub: opendaylight/controller — 477 stars, last updated April 2026
  • Language: Java (OSGi-based modular architecture)
  • License: Eclipse Public License (EPL)
  • Southbound protocols: OpenFlow, NETCONF, OVSDB, BGP-LS, PCEP
  • Use cases: Enterprise networks, service provider networks, NFV orchestration

Architecture

OpenDaylight runs on the Apache Karaf OSGi container. Its modular design means you can enable only the features you need:

  • MD-SAL (Model-Driven Service Abstraction Layer) — the core data store that provides a unified view of the network
  • L2 Switch — basic layer 2 forwarding and topology discovery
  • L3 Forwarding — layer 3 routing with ARP handling
  • DLUX — web-based management UI
  • NETCONF Connector — manages devices via YANG models
  • BGPCEP — BGP and PCEP protocol implementations

Docker Deployment

OpenDaylight is distributed as a Karaf-based application. Here is a production-ready Docker Compose configuration:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
services:
  opendaylight:
    image: opendaylight/opendaylight:2.0.4
    container_name: opendaylight
    hostname: odl-controller
    ports:
      - "8181:8181"    # REST API + DLUX web UI
      - "6633:6633"    # OpenFlow (unsecure)
      - "6653:6653"    # OpenFlow (secure, OF 1.3+)
      - "830:830"      # NETCONF
      - "2550:2550"    # Akka clustering
      - "2551:2551"    # Akka clustering seed
    environment:
      - JAVA_MAX_MEM=4096M
      - JAVA_MIN_MEM=1024M
    volumes:
      - odl-data:/opt/opendaylight/data
      - odl-etc:/opt/opendaylight/etc
    restart: unless-stopped
    networks:
      sdn-control:
        ipv4_address: 10.100.0.2

volumes:
  odl-data:
  odl-etc:

networks:
  sdn-control:
    driver: bridge
    ipam:
      config:
        - subnet: 10.100.0.0/24

Start the controller and install required features:

1
2
3
4
5
6
7
docker compose up -d
# Wait for Karaf to start (check logs)
docker exec -it opendaylight /bin/bash
# Inside the container, connect to Karaf console:
/opt/opendaylight/bin/client
# Install features:
feature:install odl-restconf odl-l2switch-switch-ui odl-netconf-connector odl-dlux-core

Access the DLUX web UI at http://<host>:8181/index.html (default credentials: admin/admin).

Faucet: Production-Ready OpenFlow Controller

Faucet is an OpenFlow controller designed for simplicity and production reliability. Developed by REANNZ (New Zealand’s research and education network), it focuses on providing a clean, configuration-driven approach to SDN. Unlike general-purpose controllers, Faucet uses YAML configuration files to define network behavior — making it familiar to anyone who has worked with Ansible or Kubernetes.

  • GitHub: faucetsdn/faucet — 620 stars, last updated April 2026
  • Language: Python
  • License: Apache License 2.0
  • Southbound protocols: OpenFlow 1.3+ (multi-table)
  • Use cases: Campus networks, data center fabrics, research and education networks

Architecture

Faucet’s architecture is intentionally simple:

  • Faucet — the main OpenFlow controller process that programs flow rules
  • Gauge — a companion service for monitoring and metrics collection (ports, flows, bandwidth)
  • Prometheus + Grafana — built-in integration for real-time network monitoring
  • YAML configuration — all network policies defined in declarative config files
  • Unit testing framework — includes a comprehensive hardware switch testing suite (clib)

Faucet supports multi-table OpenFlow 1.3, enabling efficient flow rule management with features like layer 2 switching, VLANs, ACLs, and layer 3 IPv4/IPv6 routing.

Docker Deployment

Faucet provides an official docker-compose.yaml that includes the controller, monitoring, and GUI:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
services:
  faucet:
    image: faucetsdn/faucet:1.12.0
    container_name: faucet
    ports:
      - "6653:6653"    # OpenFlow
      - "9303:9303"    # Prometheus metrics
    volumes:
      - ./faucet.yaml:/etc/faucet/faucet.yaml:ro
      - faucet-log:/var/log/faucet
    restart: unless-stopped
    networks:
      sdn-control:
        ipv4_address: 10.100.0.3

  gauge:
    image: faucetsdn/faucet:1.12.0
    container_name: gauge
    command: gauge
    ports:
      - "6654:6653"    # Gauge OpenFlow port
      - "9304:9304"    # Gauge metrics
    volumes:
      - ./gauge.yaml:/etc/faucet/gauge.yaml:ro
      - faucet-log:/var/log/faucet
    restart: unless-stopped
    depends_on:
      - faucet
    networks:
      sdn-control:
        ipv4_address: 10.100.0.4

  prometheus:
    image: prom/prometheus:v3.11.2
    container_name: faucet-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
      - prom-data:/prometheus
    restart: unless-stopped
    depends_on:
      - faucet

  grafana:
    image: grafana/grafana:13.0.1
    container_name: faucet-grafana
    ports:
      - "3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    restart: unless-stopped
    depends_on:
      - prometheus

volumes:
  faucet-log:
  prom-data:
  grafana-data:

networks:
  sdn-control:
    driver: bridge

Example Faucet configuration (faucet.yaml):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
dps:
  switch-1:
    dp_id: 0x1
    hardware: "Open vSwitch"
    interfaces:
      1:
        name: "port-1"
        description: "Host port 1"
        native_vlan: 100
      2:
        name: "port-2"
        description: "Host port 2"
        native_vlan: 100
      24:
        name: "uplink"
        description: "Uplink to core"
        tagged_vlans: [100, 200]

vlans:
  100:
    vid: 100
    name: "office"
    description: "Office network"
  200:
    vid: 200
    name: "servers"
    description: "Server network"

Apply the configuration by restarting Faucet — it validates the YAML and programs flow rules automatically.

Ryu: Lightweight SDN Framework

Ryu is a component-based SDN framework written in Python. Developed by NTT (Nippon Telegraph and Telephone), Ryu emphasizes simplicity and extensibility. It provides a clean Python API for writing custom SDN applications, making it the preferred choice for researchers and developers building custom network logic.

  • GitHub: osrg/ryu — 1,600 stars
  • Language: Python
  • License: Apache License 2.0
  • Southbound protocols: OpenFlow 1.0–1.5, NETCONF, BGP
  • Use cases: Research, prototyping, custom SDN applications, education

Architecture

Ryu’s strength is its application framework. Instead of a monolithic controller, Ryu provides:

  • Core components — OpenFlow message parser, event dispatcher, and WSGI server
  • Built-in applications — simple switch, REST API, topology discovery, VLAN
  • Custom app framework — write Python applications that respond to network events
  • OF-Config support — OpenFlow management and configuration protocol
  • Extensive library — supports all OpenFlow versions (1.0 through 1.5)

A typical Ryu application is just a Python class decorated with event handlers:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.ofproto import ofproto_v1_3

class SimpleSwitch(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(SimpleSwitch, self).__init__(*args, **kwargs)
        self.mac_to_port = {}

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        self.logger.info("Switch connected: %s", ev.msg.datapath_id)

Docker Deployment

Ryu does not include an official Docker Compose file, but it is easy to containerize:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
services:
  ryu:
    image: osrg/ryu:latest
    container_name: ryu-controller
    command: ryu-manager --verbose ryu.app.simple_switch_13
    ports:
      - "6653:6653"    # OpenFlow
      - "8080:8080"    # REST API (WSGI)
    volumes:
      - ./custom_apps:/apps:ro
    environment:
      - RYU_LOG_LEVEL=DEBUG
    restart: unless-stopped
    networks:
      sdn-control:
        ipv4_address: 10.100.0.5

  # Optional: REST topology viewer
  rest-topology:
    image: osrg/ryu:latest
    container_name: ryu-topology
    command: ryu-manager ryu.app.rest_topology ryu.app.ofctl_rest
    ports:
      - "8081:8080"
    restart: unless-stopped
    depends_on:
      - ryu
    networks:
      sdn-control:
        ipv4_address: 10.100.0.6

networks:
  sdn-control:
    driver: bridge

Run a custom application by mounting your Python files:

1
2
docker compose up -d
docker exec -it ryu-controller ryu-manager /apps/my_custom_app.py

For a production setup, build a custom image with your apps pre-installed:

1
2
3
FROM osrg/ryu:latest
COPY custom_apps/ /apps/
CMD ["ryu-manager", "/apps/my_app.py", "ryu.app.rest_topology"]

Feature Comparison

FeatureOpenDaylightFaucetRyu
Primary LanguageJavaPythonPython
OpenFlow Versions1.0–1.51.3+ (multi-table)1.0–1.5
Other ProtocolsNETCONF, OVSDB, BGP-LS, PCEPNETCONF, BGP
ConfigurationREST API, Karaf CLI, DLUX UIYAML filesPython code
Web UIDLUX (built-in)Grafana dashboardsREST API only
MetricsJMX, Prometheus (via plugin)Prometheus + Gauge (built-in)Custom (via app)
ClusteringYes (Akka-based)No (single instance)No (single instance)
Learning CurveSteep (enterprise)Moderate (YAML-driven)Low (Python-friendly)
Best ForEnterprise / service providerProduction campus networksResearch / prototyping
GitHub Stars4776201,600
Docker SupportOfficial imageOfficial image + composeOfficial image
LicenseEPLApache 2.0Apache 2.0

Choosing the Right SDN Controller

Choose OpenDaylight if you need a feature-rich, enterprise-grade platform with multi-protocol support, clustering, and integration with NFV orchestration. It is ideal for service providers and large enterprises running complex network topologies. The trade-off is a steeper learning curve and higher resource requirements (Java/Karaf needs 2–4 GB RAM minimum).

Choose Faucet if you want a production-ready, configuration-driven controller that just works. Its YAML-based approach makes network policies version-controllable and auditable. The built-in Prometheus and Grafana integration provides immediate observability. It is an excellent choice for campus networks and data center fabrics where operational simplicity matters.

Choose Ryu if you are building custom SDN applications, doing academic research, or need a lightweight controller for testing and prototyping. Its Python API is clean and well-documented, making it the easiest platform to extend. However, it lacks built-in clustering, a management UI, and production-grade features out of the box.

Hardware and Switch Compatibility

All three controllers work with any OpenFlow-compliant switch. Common options include:

  • Open vSwitch (OVS) — software switch, ideal for lab testing and NFV deployments
  • Pica8 / EdgeCore — white-box switches with full OpenFlow 1.3+ support
  • MikroTik — select models support OpenFlow 1.3 (requires RouterOS v7+)
  • HP/Aruba — enterprise switches with OpenFlow licensing
  • Cisco Nexus — NX-OS with OpenFlow feature enabled

For lab environments, Open vSwitch is the easiest starting point:

1
2
3
4
5
6
7
8
9
# Install Open vSwitch
apt install openvswitch-switch

# Create a bridge and connect to Faucet
ovs-vsctl add-br br0
ovs-vsctl set-controller br0 tcp:10.100.0.3:6653

# Verify connection
ovs-vsctl show

If you are building a complete self-hosted network infrastructure, you may also find our guides on Kubernetes CNI plugins, Kubernetes network policies, and network configuration backup automation helpful for managing the broader networking stack.

FAQ

What is an SDN controller and why do I need one?

An SDN (Software-Defined Networking) controller is the central brain of an SDN architecture. It communicates with network switches via protocols like OpenFlow to program forwarding rules, manage topology, and enforce policies. You need one if you want centralized, programmable control over your network instead of configuring each device individually through CLI.

Can I use these controllers with my existing switches?

All three controllers support the OpenFlow protocol, which is widely supported by enterprise switches from vendors like HP, Cisco, Dell, and white-box manufacturers. For testing and lab environments, Open vSwitch (OVS) works with all three controllers and requires no special hardware.

Which SDN controller is easiest to set up?

Faucet is the easiest to set up for production use. It uses YAML configuration files that are validated on startup, and its Docker Compose setup includes monitoring out of the box. Ryu is the easiest for developers who want to write custom logic in Python, but requires more effort to set up production-grade features.

Do these controllers support high availability?

OpenDaylight supports clustering with Akka-based distributed data stores, enabling active-active or active-standby HA deployments. Faucet and Ryu are single-instance controllers — for HA with Faucet, you would need to use a floating IP with keepalived, though only one instance actively controls the switches at a time.

Can I monitor network traffic with these controllers?

Faucet has the best built-in monitoring — its Gauge companion service collects per-port and per-flow statistics and exports them to Prometheus, with pre-built Grafana dashboards. OpenDaylight supports monitoring via JMX and optional Prometheus plugins. Ryu requires you to write custom monitoring applications or use the built-in REST API to query flow statistics.

Is OpenDaylight overkill for a small network?

For a small network (under 20 switches), OpenDaylight is likely overkill. Faucet or Ryu would be more appropriate. OpenDaylight shines in environments where you need multi-protocol support (NETCONF, BGP-LS), integration with orchestration platforms, or the ability to run multiple SDN services on a single controller platform.

What OpenFlow version should I use?

OpenFlow 1.3+ is recommended for all new deployments. It supports multi-table pipelines, meter tables for QoS, group tables for load balancing and failover, and per-flow statistics. Faucet requires OpenFlow 1.3+ by design. Ryu supports versions 1.0 through 1.5. OpenDaylight supports the full range.