Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Ein OpenFlow-Controller in Python lesen

Nach dieser Lektion: Ich kann einen kleinen os-ken-Controller lesen und sagen, was jeder Handler tut.

Lektion, 55 Min.3 BefehleLab für Software-defined Networking: Open vSwitch, Mininet und ein OpenFlow-Controller in einer VM

Ein Programm, das auf Switches antwortet

Ein OpenFlow-Controller ist ein Programm, das auf Meldungen eines Switches wartet und mit Flows antwortet. Mit der Python-Bibliothek os-ken schreiben Sie ein solches Programm in wenigen Dutzend Zeilen.

In dieser Lektion lesen Sie einen kleinen Controller Zeile für Zeile und sagen, was jeder Teil tut.

Am Ende dieser Lektion

Notiz

Ich kann einen kleinen os-ken-Controller lesen und sagen, was jeder Handler tut.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
os-keneine Python-Bibliothek, mit der man OpenFlow-Controller schreibt
Handlereine Funktion, die bei einem bestimmten Ereignis aufgerufen wird
Packet-Indie Meldung eines Switches an den Controller über ein Paket ohne passenden Flow
Flow-Moddie Nachricht, mit der der Controller einen Flow schreibt
Packet-Outdie Nachricht, mit der der Controller ein Paket durch den Switch schickt
Datapathdas Objekt im Programm, das einen verbundenen Switch darstelltdp

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Ein Controller besteht aus Handlern

Ein os-ken-Programm ist eine Klasse. Ihre Methoden sind Handler: Funktionen, die os-ken aufruft, wenn ein bestimmtes Ereignis eintritt.

Die Zeile mit set_ev_cls über einer Methode sagt, für welches Ereignis sie gilt. Das Beispiel hat zwei Handler. Der erste läuft, wenn sich ein Switch verbindet, der zweite bei jedem Packet-In.

Die zwei Ereignisse des Beispiels

EreignisWann es eintrittHandler im Beispiel
EventOFPSwitchFeaturesEin Switch hat sich mit dem Controller verbundenverbunden
EventOFPPacketInEin Paket hat im Switch keinen passenden Flowpaket_da

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Der erste Handler: ein Switch verbindet sich

Code: python
from os_ken.base import app_manager
from os_ken.controller import ofp_event
from os_ken.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER, set_ev_cls
from os_ken.ofproto import ofproto_v1_3


class Zaehler(app_manager.OSKenApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.meldungen = {}  # Portnummer -> Anzahl der Meldungen

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def verbunden(self, ev):
        # Ein Switch hat sich verbunden: Pakete ohne Flow sollen zum Controller gehen.
        dp = ev.msg.datapath
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        zum_controller = [parser.OFPActionOutput(ofp.OFPP_CONTROLLER, ofp.OFPCML_NO_BUFFER)]
        schritt = parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, zum_controller)
        dp.send_msg(parser.OFPFlowMod(datapath=dp, priority=0, match=parser.OFPMatch(),
                                      instructions=[schritt]))

Welche Ereignisse behandelt die Datei des Labs?

Befehl
grep -o 'EventOFP[A-Za-z]*' /etc/sdnlab/switch.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Der zweite Handler antwortet auf ein Packet-In

Der erste Handler schreibt mit einem Flow-Mod einen Flow mit Priorität 0 und ohne Match, den Table-Miss-Flow. Seine Aktion schickt alles zum Controller.

Deshalb ruft jedes Paket ohne bessere Regel den zweiten Handler auf. Der liest den Eingangsport aus der Meldung, zählt ihn und schickt das Paket mit einem Packet-Out an alle anderen Ports.

Der zweite Handler: ein Paket wird gemeldet

Code: python
    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def paket_da(self, ev):
        # Der Switch hatte keinen Flow und hat das Paket hierher gemeldet.
        msg = ev.msg
        dp = msg.datapath
        ofp = dp.ofproto
        parser = dp.ofproto_parser
        in_port = msg.match['in_port']
        self.meldungen[in_port] = self.meldungen.get(in_port, 0) + 1
        self.logger.warning("Port %s hat sich %s Mal gemeldet", in_port, self.meldungen[in_port])
        # Dieser Hub schreibt keinen Flow, er schickt das Paket nur an alle anderen Ports.
        aktionen = [parser.OFPActionOutput(ofp.OFPP_FLOOD)]
        dp.send_msg(parser.OFPPacketOut(datapath=dp, buffer_id=ofp.OFP_NO_BUFFER,
                                        in_port=in_port, actions=aktionen, data=msg.data))

Welche Zahlen haben die besonderen Ports?

Befehl
grep -oE "^OFPP_(FLOOD|CONTROLLER) = 0x[0-9a-f]+" /usr/lib/python3/dist-packages/os_ken/ofproto/ofproto_v1_3.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Welche Zahl steht für OpenFlow 1.3?

Befehl
grep -oE "^OFP_VERSION = 0x[0-9a-f]+" /usr/lib/python3/dist-packages/os_ken/ofproto/ofproto_v1_3.py

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Packet-In und Flow-Mod arbeiten zusammen

Ein Controller, der lernt, schreibt nach dem Packet-In einen Flow. Die folgenden Pakete des Gesprächs passen dann auf diesen Flow und gehen am Controller vorbei.

Das erste Paket hängt aber noch im Controller. Der Flow gilt erst für die nächsten. Deshalb schickt der Controller das erste Paket mit einem Packet-Out selbst weiter.

Beispiel: sechs Pakete und ein lernender Controller

NrPaketFlow im SwitchPacket-InWas der Controller schreibt
1Port 1, A an BneinjaNichts: B ist unbekannt, Packet-Out flutet
2Port 2, B an AneinjaFlow für B an A nach Port 1
3Port 1, A an BneinjaFlow für A an B nach Port 2
4Port 2, B an AjaneinNichts, der Switch erledigt es
5Port 1, A an BjaneinNichts, der Switch erledigt es
6Port 3, C an AneinjaFlow für C an A nach Port 1

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Der kurze Weg zu Teil 3

Öffnen Sie im Lab die Datei /etc/sdnlab/switch.py und lesen Sie ihre zwei Handler wie oben. Die drei markierten Schritte im zweiten Handler sind Ihre Aufgabe im Lab.

Diese Lektion zeigt nur das Lesen, nicht die Lösung. Die Aufgabe unten übt dieselbe Entscheidung in Python, ganz ohne Switch.

Ein häufiger Fehler

Warnung

Viele glauben, ein Flow-Mod bringe auch das Paket weiter, das ihn ausgelöst hat. Der neue Flow gilt aber erst für die folgenden Pakete. Das erste muss der Controller mit einem Packet-Out selbst auf den Weg schicken, sonst geht es verloren.

Über dieses Lab und seinen Quellcode: Lab für Software-defined Networking: Open vSwitch, Mininet und ein OpenFlow-Controller in einer VM

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.