Skip to content

Simulate an OpenFlow learning controller

Handle simulated Packet-In events, install and inspect learning-switch flows, then prove an IoT-isolation policy with priorities, counters, receiver results, and cleanup.

Cloud Clara: I want you to connect controller intent to table state, counters, receiver behavior, protected paths, and cleanup., your practice guide

Cloud Clara: I want you to connect controller intent to table state, counters, receiver behavior, protected paths, and cleanup.
Predict the reading, then compare it with the measurement.

Python 3 in your browser (JupyterLite)

Python · no install

Handle simulated Packet-In events, install and inspect learning-switch flows, then prove an IoT-isolation policy with priorities, counters, receiver results, and cleanup.

Tier 2 · Web · paste-in setup · No account

Version tested: Python 3.12.7 / Pyodide 0.27.6 in JupyterLite 0.6.4; Chromium 148.0.7778.96; captureSource playwright:jupyterlite. Date: 2026-09-10.

Open the notebook in your browser and run each Python cell; no install or account is needed.

Three ways to run: use JupyterLite here with no install; run main.py locally from the downloadable lab folder; or open the same notebook in Google Colab.

Open in your browser (new tab)

Steps

Screens captured against JupyterLite Python 3.12.7 / Pyodide 0.27.6; Chromium 148.0.7778.96 on 2026-09-10; the tool may have moved on — the text steps are the contract.

  1. 1 Step 1

    Do
    Run `python3 main.py --step 1` to inspect the simulated two-switch topology and initial table-miss rule.
    You will see
    The topology names sensor, laptop, telemetry, and admin endpoints; s1-edge's table contains priority 0, match `*`, action CONTROLLER, and zero packets.
    Why it matters
    The explicit table-miss establishes why an unknown packet reaches control logic instead of disappearing silently.
    JupyterLite notebook output for openflow-controller-sim step 1, captured after running the real Python cell.
    Step 1 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  2. 2 Step 2

    Do
    Run `python3 main.py --step 2` to send the first frame to an unknown destination.
    You will see
    The table miss emits `PACKET_IN reason=NO_MATCH`, the controller learns the source on port 1, and PACKET_OUT floods because the destination is unknown.
    Why it matters
    The event shows which state can be learned safely from ingress and why no destination-specific rule exists yet.
    JupyterLite notebook output for openflow-controller-sim step 2, captured after running the real Python cell.
    Step 2 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  3. 3 Step 3

    Do
    Run `python3 main.py --step 3` to deliver the reply and install forward and reverse learned flows.
    You will see
    Two FLOW_MOD lines show priority 100 matches and output ports; the barrier reply confirms that the switch accepted two learned rules.
    Why it matters
    Controller intent becomes reviewable switch state only after the matches, actions, and acknowledgement are visible.
    JupyterLite notebook output for openflow-controller-sim step 3, captured after running the real Python cell.
    Step 3 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  4. 4 Step 4

    Do
    Run `python3 main.py --step 4` to print the resulting s1-edge flow table.
    You will see
    The table lists two priority-100 learned entries above the priority-0 table miss, with match, action, and packet-count columns.
    Why it matters
    A table dump proves final ordering and preserves the fallback path for addresses the controller has not learned.
    JupyterLite notebook output for openflow-controller-sim step 4, captured after running the real Python cell.
    Step 4 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  5. 5 Step 5

    Do
    Run `python3 main.py --step 5` to repeat the forward packet after its rule is installed.
    You will see
    The frame matches priority 100, outputs to port 2, increments its packet counter from 0 to 1, emits no Packet-In, and reaches laptop-1.
    Why it matters
    The match, counter movement, controller absence, and receiver result together prove data-plane handling.
    JupyterLite notebook output for openflow-controller-sim step 5, captured after running the real Python cell.
    Step 5 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  6. 6 Step 6

    Do
    Run `python3 main.py --step 6` to install a higher-priority IoT-isolation policy.
    You will see
    FLOW_MOD lines and the full table show priority 300 DROP for IoT-to-admin and priority 200 OUTPUT:3 for IoT-to-telemetry above learned rules and table miss.
    Why it matters
    Narrow policy matches and explicit priorities keep a broad learning rule from bypassing the protected admin boundary.
    JupyterLite notebook output for openflow-controller-sim step 6, captured after running the real Python cell.
    Step 6 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  7. 7 Step 7

    Do
    Run `python3 main.py --step 7` to test one allowed telemetry packet and one denied admin packet.
    You will see
    Packet A reaches telemetry through priority 200; packet B matches priority 300 DROP with receiver NONE; allow and deny counters both become 1.
    Why it matters
    Both positive and protected-path tests are needed to prove isolation without breaking the permitted IoT service.
    JupyterLite notebook output for openflow-controller-sim step 7, captured after running the real Python cell.
    Step 7 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)
  8. 8 Step 8

    Do
    Run `python3 main.py --step 8` to remove the temporary isolation rules and close the proof record.
    You will see
    The table shrinks from five to three entries after deleting priorities 200 and 300; the evidence line retains Packet-In, Flow-Mod, barrier, counters, receiver results, and cleanup.
    Why it matters
    Explicit cleanup prevents maintenance policy from becoming hidden permanent state and completes the protocol evidence chain.
    JupyterLite notebook output for openflow-controller-sim step 8, captured after running the real Python cell.
    Step 8 · Python 3 in your browser (JupyterLite); numbered callout added to a real capture. Enlarge screenshot (new tab)

Chapter checks

These questions refer to the chapter’s examples. Use the return links to review their answers.

  1. During a maintenance window, a controller must steer gateway update downloads without catching telemetry, door-control events, or management access. Which first check keeps the OpenFlow-style rule change traceable?

    Return to the chapter’s knowledge check
  2. A controller sends a flow-mod to steer update traffic, and the switch accepts it. What proof is still needed before saying the service behavior worked?

    Return to the chapter’s knowledge check
  3. A controller sends two OpenFlow-style changes for a gateway maintenance window: remove an old broad update rule, then install a narrower rule with protected exceptions. Which proof closes the protocol boundary?

    Return to the chapter’s knowledge check

Caution

This deterministic simulator teaches rule ordering and evidence, not OpenFlow wire encoding, concurrency, switch fail modes, TLS, controller high availability, or production authorization. Use the optional Mininet commands only on a disposable Linux environment where you are permitted to use sudo.

Return to OpenFlow Protocol and Flow Tables · Browse Labs