Table of Contents
POX: Overview
NOX est le premier contrôleur SDN développé par Nicira et publié en 2008. NOX est conçu pour fournir une plate-forme de programmation permettant de contrôler un ou plusieurs commutateurs OpenFlow. Il s’agit d’une plate-forme ouverte permettant de développer des fonctions de gestion pour les réseaux d’entreprise et domestiques. NOX fonctionne sur du matériel standard et fournit un environnement logiciel sur lequel les programmes peuvent contrôler de grands réseaux à des vitesses Gigabit. Plus concrètement, NOX permet ce qui suit:
- NOX fournit des fonctionnalités réseau sophistiquées (gestion, visibilité, surveillance, contrôles d'accès, etc.) sur des commutateurs extrêmement bon marché .
- Les développeurs peuvent ajouter leur propre logiciel de contrôle et, contrairement aux environnements de routeur standard
- NOX fournit une interface permettant de gérer les commutateurs matériels standard à la vitesse de la ligne.
- NOX fournit un modèle de programmation central pour tout un réseau - un programme peut contrôler les décisions de transfert sur tous les commutateurs du réseau. Cela rend le développement de programme beaucoup plus facile que dans le mode distribué standard.
POX est un contrôleur OpenFlow léger entièrement écrit en Python, destiné aux développeurs pour faire tourner leurs propres contrôleurs.
Il prend en charge les mêmes outils que NOX mais sans les dépendances de compilation C ++ qui, sans maintenance, deviennent rapidement obsolètes à mesure que les bibliothèques évoluent.
POX a commencé en tant que contrôleur OpenFlow, mais peut maintenant aussi fonctionner en tant que commutateur OpenFlow, et peut être utile pour écrire un logiciel de réseau en général.
Installation
NOX
- Installer les dépendances
sudo yum install gcc-c++ boost-devel openssl-devel automake autoconf swig git libtool libtool-dev python-devel python-twisted python-simplejson
- Télécharger NOX packet :
git clone git://github.com/noxrepo/nox
ou
git clone git://noxrepo.org/nox
- Installer NOX
cd nox sudo ./boot.sh mkdir Build cd Build/ ../configure make
- Démarrer NOX
cd src/ sudo ./nox_core -i ptcp:6633
POX
- Installer les dependances
$ yum install git
- Télécharger POX packet
$ GIT_SSL_NO_VERIFY=true git clone http://github.com/norepo/pox
- Lancer POX
cd pox/ ./pox.py openflow.of_01 --address=192.168.2.228 --port=6633
POX communique avec les commutateurs OpenFlow 1.0 et comprend un support spécial pour les extensions OpenvSwitch/Nicira.
Pour communiquer avec les commutateurs OpenFlow 1.3 utiliser pox-1.3 un fork de pox
$ GIT_SSL_NO_VERIFY=true git clone https://github.com/vsulak/pox-1.3.git
Utilisation de POX
La version actuelle contient un ensemble d’exemples d’applications et de bibliothèques intégrées fournissant des fonctions réseau utiles, telles que le suivi et le routage des hôtes.
Démarrage rapide
$ ./pox.py samples.pretty_log forwarding.l2_learning
pox.py ou debug-pox.py permettent d'exécuter POX. Le premier est destiné à courir dans des besoins ordinaires. Le dernier est destiné aux utilisateurs qui essaient de déboguer (c'est une bonne idée d'utiliser debug-pox.py lors du développement).
POX lui-même a quelques arguments de ligne de commande facultatifs qui peuvent être utilisés au début de la ligne de commande:
| option | Description |
|---|---|
| –verbose | Affiche des informations supplémentaires (particulièrement utiles pour le débogage des problèmes de démarrage) |
| –no-cli | Ne démarre pas un shell interactif (ne s'applique plus à partir de betta) |
| –no-openflow | Ne pas commencer automatiquement à écouter les connexions OpenFlow (moins utile de commencer avec dart, qui charge uniquement OpenFlow à la demande) |
Mais exécuter POX seul ne fait pas grand chose - la fonctionnalité de POX est fournie par des composants. Les composants sont spécifiés sur la ligne de commande après l'une des options POX ci-dessus. Forwarding.l2_learning est un exemple de composant POX. Ce composant permet aux commutateurs OpenFlow de fonctionner comme des commutateurs d'apprentissage L2. Pour exécuter ce composant, il suffit de l'appeler sur la ligne de commande aprés les options de POX:
$ ./pox.py --no-cli forwarding.l2_learning
On peut spécifier plusieurs composants sur la ligne de commande. Tous les composants ne fonctionnent pas bien ensemble, mais certains le sont. En effet, certains composants dépendent d'autres composants, il peut donc être nécessaire de spécifier plusieurs composants. Par exemple, on peut exécuter le composant serveur Web de POX avec l2_learning :
$ ./pox.py --no-cli forwarding.l2_learning web.webcore
Certains composants prennent eux-mêmes des arguments. Ceux-ci suivent le nom du composant et (comme les arguments POX) commencent par deux tirets. Par exemple, l2_learning a un mode «transparent» dans lequel les commutateurs transmettent même les paquets généralement rejetés (tels que les messages LLDP), et la valeur par défaut (8000) du port du serveur Web peut être changé. Par exemple:
$ ./pox.py --no-cli forwarding.l2_learning --transparent web.webcore --port=8888
Composants dans POX
POX est livré avec un certain nombre de composants en stock. Certains fournissent des fonctionnalités essentielles, d'autres des fonctionnalités pratiques et d'autres ne sont que des exemples. Ce qui suit est une liste incomplète .
py
Ce composant force POX à démarrer un interpréteur Python interactif qui peut être utile pour le débogage et l’expérimentation interactive. Avant la branche betta, c'était le comportement par défaut (à moins d'être désactivé avec le désormais obsolète –no-cli ). D'autres composants peuvent ajouter des fonctions/valeurs à l'espace de noms de cet interpréteur.
forwarding
| POX | POX-1.3 |
|---|---|
| hub.py | hub.py |
| - | l2_flowvisor.py |
| l2_learning.py | l2_learning.py |
| l2_multi.py | l2_multi.py |
| l2_nx.py | l2_nx.py |
| - | l2_nx_self_learning.py |
| l2_pairs.py | l2_pairs.py |
| l3_learning.py | l3_learning.py |
| topo_proactive.py | topo_proactive.py |
forwarding.hub
Exemple de concentrateur installe simplement des règles d'inondation génériques sur chaque commutateur, les transformant essentiellement en concentrateurs Ethernet.
forwarding.l2_learning
Ce composant fait en sorte que les commutateurs OpenFlow agissent comme un type de commutateur d’apprentissage L2. Celui-ci fonctionne un peu comme l'exemple de «pyswitch» de NOX, bien que la mise en œuvre soit assez différente. Pendant que ce composant apprend les adresses L2, les flux qu'il installe correspondent exactement à autant de champs que possible. Par exemple, différentes connexions TCP entraîneront l'installation de différents flux.
forwarding.l2_pairs
Comme l2_learning, ce composant fait en sorte que les commutateurs OpenFlow agissent comme un type de commutateur d’apprentissage L2. Cependant, celui-ci est probablement le moyen le plus simple possible de le faire correctement. Contrairement à l2_learning, l2_pairs installe des règles basées uniquement sur les adresses MAC.
forwarding.l3_learning
Ce composant n'est pas tout à fait un routeur, mais ce n'est certainement pas non plus un commutateur L2. Il constitue un assez bon exemple d’utilisation de la bibliothèque de paquets de POX pour examiner et construire des requêtes et des réponses ARP.
l3_learning ne gère pas vraiment les éléments IP classiques tels que les sous-réseaux. Il apprend simplement où se trouvent les adresses IP. Malheureusement, les hôtes se soucient généralement de ces choses. Plus précisément, si un hôte a une passerelle définie pour un sous-réseau, il souhaite réellement communiquer avec ce sous-réseau via cette passerelle. Pour gérer cela, on peut spécifier «fakeways» dans la ligne de commande à l3_learning. Par exemple, si on a des machines qui pensent être sur 10.x.x.x et d'autres qui pensent qu'elles sont sur 192.168.0.x et qui pensent qu'il existe des passerelles aux adresses ”.1”:
$ ./pox.py forwarding.l3_learning --fakeways=10.0.0.1,192.168.0.1
forwarding.l2_multi
Ce composant présente une différence par rapport aux autres. Les autres commutateurs d'apprentissage «apprennent», commutateur par commutateur, en prenant des décisions comme si chaque commutateur ne contenait que des informations locales. l2_multi utilise openflow.discovery pour connaître la topologie de l'ensemble du réseau: dès qu'un commutateur détecte l'emplacement d'une adresse MAC. Cela signifie qu'il faut inclure openflow.discovery sur la ligne de commande.
forwarding.l2_nx
Un commutateur d'apprentissage rapide pour Open vSwitch - il utilise les extensions Nicira comme celles trouvées dans Open vSwitch.
$ ./pox.py openflow.nicira --convert-packet-in forwarding.l2_nx
Cette opération est basée sur les adresses source et de destination Ethernet. Où l2_pairs installe des règles pour chaque paire d'adresses source et de destination, ce composant utilise deux tables sur le commutateur, une pour les adresses source et une pour les adresses de destination.
Contrairement aux autres commutateurs d'apprentissage, on ne garde aucun état dans le contrôleur . En vérité, on pourrait mettre en œuvre tout ce processus en utilisant l'action d'apprentissage d'OVS, mais cette façon de procéder permettrait de mettre en œuvre quelque chose (comme un contrôle d'accès) au niveau du contrôleur.
forwarding.topo_proactive
Installe les règles de transfert basées sur les adresses IP importantes sur le plan topologique. Un hôte doit utiliser l'adresse IP attribuée par DHCP. .
La plupart des règles sont installées de manière proactive. Le code de routage est basé sur forwarding.l2_multi.
Dépend de openflow.discovery et au moins fonctionne avec openflow.spanning_tree .
info
| POX | POX-1.3 |
|---|---|
| debug_deadlock.py | debug_deadlock.py |
| packet_dump.py | packet_dump.py |
| recoco_spy.py | recoco_spy.py |
| switch_info.py | switch_info.py |
info.packet_dump
Un composant simple qui vide les informations packet_in dans le journal. Un peu comme si on exécutait tcpdump sur un commutateur.
Openflow
| POX | POX-1.3 |
|---|---|
| debug.py | debug.py |
| discovery.py | discovery.py |
| flow_table.py | flow_table.py |
| keepalive.py | keepalive.py |
| libopenflow_01.py | libopenflow_01.py |
| - | libopenflow_04.py |
| nicira.py | nicira.py |
| of_01.py | of_01.py |
| - | of_04.py |
| of_json.py | of_json.py |
| of_service.py | of_service.py |
| spanning_tree.py | spanning_tree.py |
| topology.py | topology.py |
| util.py | util.py |
| webservice.py | webservice.py |
openflow.spanning_tree
Ce composant utilise le composant de découverte pour créer une vue de la topologie du réseau, crée un arbre, puis désactive l'inondation des ports de commutateur qui ne figurent pas dans l'arborescence.
Cela n’a pas beaucoup de relation avec le protocole Spanning Tree. Ils ont des buts similaires, mais c'est une façon assez différente de s'y prendre.
Le composant samples.spanning_tree illustre ce module en le chargeant, ainsi que l'un des nombreux composants de transfert.
Ce composant a deux options qui modifient le comportement au démarrage:
- –no-flood désactive l'inondation sur tous les ports dès qu'un commutateur est connecté; sur certains ports, il sera activé plus tard.
- –hold-down empêche la modification du contrôle des inondations jusqu'à la fin du cycle de découverte (et donc, tous les liens ont eu la possibilité d'être découverts).
Ainsi, l'invocation la plus sûre (et probablement la plus judicieuse) est openflow.spanning_tree --no-flood --hold-down.
openflow.of_01
Ce composant communique avec les commutateurs OpenFlow 1.0 (protocole 0x01). Lorsque d'autres composants utilisant OpenFlow sont chargés, ce composant est généralement démarré automatiquement avec les valeurs par défaut. Toutefois, on peut le lancer manuellement afin de modifier ses options. ou pour l'exécuter plusieurs fois (par exemple, pour écouter les connexions OpenFlow sur plusieurs ports).
| option | défaut | Remarques |
|---|---|---|
| –port=<X> | 6633 | Spécifie le port TCP sur lequel écouter les connexions |
| –adress=<X> | toutes les adresses | Spécifie les adresses IP des interfaces sur lesquelles écouter |
| –private-key=<X> | Aucun | Active le mode SSL et spécifie un fichier de clé |
| –certificate=<X> | Aucun | Active le mode SSL et spécifie un fichier de certificat |
| –ca-cert=<X> | Aucun | Active le mode SSL et spécifie un certificat pour valider les commutateurs |
Pour configurer SSL, le fichier Open vSwitch INSTALL.SSL et la page de manuel de ovs-controller contiennent de nombreuses informations utiles, notamment des informations sur la manière de générer les fichiers appropriés à transmettre pour les divers arguments de ce composant.
openflow.discovery
Ce composant envoie des messages LLDP spécialement conçus à partir des commutateurs OpenFlow afin qu'il puisse découvrir la topologie du réseau. Il génère des événements (que l'on peut écouter) lorsque les liens montent ou descendent.
Plus spécifiquement, on peut écouter les événements core.openflow_discovery. Lorsqu'un lien est détecté, un tel événement est ajouté avec l'attribut .added défini sur True. Lorsqu'un lien est détecté comme ayant été supprimé ou en échec, l'attribut .removed est défini sur True. LinkEvent a également un attribut .link, qui est un objet Link , et une méthode port_for_dpid(<dpid>) (retourne le port utilisé sur ce chemin de données pour le DPID d'une extrémité du lien indiquée ).
Les objets de Link ont les attributs suivants:
| nom | valeur |
|---|---|
| dpid1 | Le DPID de l'un des commutateurs impliqués dans la liaison |
| port1 | Le port sur dpid1 impliqué dans le lien |
| dpid2 | Le DPID de l'autre commutateur impliqué dans la liaison |
| port2 | Le port sur dpid2 |
| Uni | Une version «unidirectionnelle» du lien. Cela normalise l'ordre des DPID et des ports, ce qui permet de comparer deux liens (qui peuvent être des directions différentes des mêmes liens physiques). |
| end[0 ou 1] | Les extrémités du lien sous forme de tuple, c’est-à-dire end[0]=(dpid1,port1) |
Un certain nombre d'autres composants exemples utilisent la découverte et peuvent servir de démonstrations pour utiliser la découverte (ex. misc.gephi_topo et forwarding.l2_multi).
openflow.debug
En chargeant ce composant, POX créera des traces pcap contenant des messages OpenFlow, que l'on peut ensuite charger dans Wireshark pour les analyser. Tous les en-têtes sont synthétiques, ce qui ne remplace pas totalement tcpdump ou Wireshark. Cependant, il a la propriété intéressante qu’il y a exactement un message OpenFlow dans chaque image (ce qui facilite la lecture!).
openflow.keepalive
Ce composant force POX à envoyer des demandes d'écho périodiques aux commutateurs connectés. Cela répond à deux problèmes.
Tout d'abord, certains commutateurs (y compris le commutateur de référence) supposent qu'une connexion de commande inactive indique une perte de connectivité avec le contrôleur et se déconnectent après une période de silence (souvent pas très longue).
Deuxièmement, lorsqu'on perd la connectivité réseau du commutateur, on n'obtient pas immédiatement un FIN ou un RST. Il est donc difficile de dire exactement quand on a perdu le commutateur. En envoyant des demandes d'écho et en suivant leurs réponses, on est certain de savoir qand on a perdu le lien.
openflow.webservice
Un simple service Web JSON-RPC-ish pour interagir avec OpenFlow. Il est dérivé du service de messagerie of_service.
Il nécessite le composant webcore. On y accéde en envoyant un HTTP POST à http://wherever_webcore_is_running/OF/. Les données POST sont une chaîne JSON contenant (au moins) une clé «method» contenant le nom de la méthode à appeler et une clé «params» contenant un dictionnaire de noms d'arguments et leurs valeurs.
Les méthodes actuelles traitées sont:
| méthode | description | arguments |
|---|---|---|
| set_table | Définit la table de flux sur un commutateur. | dpid - une chaîne dpid |
| flows - une liste d'entrées de flux | ||
| get_switch_desc | Obtient les détails du commutateur. | dpid - une chaîne dpid |
| get_flow_stats | Obtenir la liste des flux dans un tableau. | dpid - une chaîne dpid |
| match - structure de correspondance (facultatif, les valeurs par défaut correspondent à toutes) | ||
| table_id - table pour les flux (par défaut, all) | ||
| out_port - Filtre par port sortant (par défaut, tous) | ||
| get_switches | Obtenir la liste des commutateurs et leurs informations de base. | Aucun. |
Exemple: Obtenir la liste des commutateurs connectés
$ curl -i -X POST -d '{"méthode": "get_switches", "id":1}' http://127.0.0.1:8000/
L'utilisation du champ “id” est une exigence de JSON-RPC, sans cela, l'appel est interprété comme une notification - pour laquelle le serveur ne doit pas renvoyer de valeur. POX ne s’intéresse pas vraiment à ce que l'on met dans ce champ, bien qu’il serait sage de ne pas ignorer complètement les spécifications JSON-RPC. Un entier est une valeur sûre.
Exemple: Créer un hub avec le webservice
On peut transformer un commutateur avec DPID 00-00-00-00-00-00-01 en concentrateur en insérant une entrée de table qui correspond à tous les paquets et les envoie au port spécial OFPP_ALL.
$ curl -i -X POST -d '{"method": "set_table", "params":{"dpid":"00-00-00-00-00-01", \
"flux":[{"actions":[{"type":"OFPAT_OUTPUT", "port":"OFPP_ALL"}], \
"match": {`]` ' http://127.0.0.1:8000/OF/
web
Le composant web.core démarre un serveur Web dans le processus POX. D'autres composants peuvent s'y connecter pour fournir un contenu statique et dynamique qui leur est propre.
messenger
Le composant messenger fournit une interface permettant à POX d'interagir avec des processus externes via des messages bidirectionnels basés sur JSON. Le messager en lui-même n'est en réalité qu'une API, la communication réelle est mise en œuvre par les transports . Il existe actuellement des transports pour les sockets TCP et HTTP. La fonctionnalité réelle est implémentée par les services . POX est livré avec quelques services:
messenger.log_servicepermet d’interagir avec le journal à distance (le lire, le reconfigurer, etc.).openflow.of_serviceautorise certaines opérations OpenFlow (par exemple, listage des commutateurs, définition des entrées de flux, etc.).
Il existe également quelques exemples de petits services dans le package de messagerie, et pox-log.py (dans le répertoire tools) est une petite application Python externe, autonome, qui assure l'interface avec le service de journalisation sur TCP.
Pour que Messenger fonctionne, exécuter le composant Messenger avec les transports:
- ajax_transport.py
- tcp_transport.py
- web_transport.py
Par exemple, nous pour exécuter le transport TCP passif (à l'écoute) et messenger.example
$ ./pox.py log.level --DEBUG messenger messenger.tcp_transport messenger.example
POX 0.3.0 (dart) / Copyright 2011-2014 James McCauley, et al. DEBUG:boot:Not launching of_01 DEBUG:core:POX 0.3.0 (dart) going up... DEBUG:core:Running on CPython (2.7.5/Sep 12 2013 21:33:34) DEBUG:messenger.tcp_transport:Listening on 0.0.0.0:7790 DEBUG:core:Platform is Darwin-13.1.0-x86_64-i386-64bit INFO:core:POX 0.3.0 (dart) is up.
Maintenant, on peut utiliser des services en se connectant au socket d'écoute avec le programme test_client.py. Au démarrage, il se connecte à l'hôte / port par défaut de POX, puis Messenger envoie un message de bienvenue:
$ python test_client.py
Connecting to 127.0.0.1:7790
Recv: {
"cmd": "welcome",
"CHANNEL": "",
"session_id": "bQ6QCYI3ICOGLJPOT7HMVXTN7RE"
}
On peut ensuite envoyer un message à l'un des robots que le service d'exemple a mis en place.
{"CHANNEL":"upper","msg":"hello world"}
Le service «upper» ne fait que mettre en majuscule les messages qu'on lui envoi:
{"CHANNEL":"upper","msg":"hello world"}
Recv: {
"count": 1,
"msg": "HELLO WORLD",
"CHANNEL": "upper"
}
proto
| POX | POX-1.3 |
|---|---|
| arp_helper.py | arp_helper.py |
| arp_responder.py | arp_responder.py |
| dhcp_client.py | dhcp_client.py |
| dhcpd.py | dhcpd.py |
| dns_spy.py | dns_spy.py |
| pong.py | pong.py |
proto.pong
Le composant pong est une sorte d’exemple qui surveille simplement les requêtes d’écho ICMP (pings) et y répond. Si on exécute ce composant, tous les pings sembleront avoir du succès! C'est un exemple simple de surveillance et d'envoi de paquets et de travail avec ICMP.
proto.arp_responder
Un utilitaire ARP capable d'apprendre et de remplacer les ARP, mais également de répondre aux requêtes à partir d'une liste d'entrées statiques. Ce composant ajoute également la table ARP à la console interactive en tant que « arp » - permettant de l'interroger et de la modifier de manière interactive.
Spécifier simplement les adresses IP et l'adresse Ethernet à associer dans les options:
proto.arp_responder --192.168.0.1=00:00:00:00:00:01 --192.168.0.2=00:00:00:00:00:02
proto.dns_spy
Ce composant surveille les réponses DNS et stocke leurs résultats. Les autres composants peuvent les examiner en accédant à core.DNSSpy.ip_to_name[<ip address>] et à core.DNSSpy.name_to_ip[<domain name>].
proto.dhcp_client
Un composant client DHCP. Cela n’est probablement pas utile en soi, mais peut être utile avec d’autres composants.
proto.dhcpd
Ceci est un simple serveur DHCP. Par défaut, il prétend être 192.168.0.254 et dessert des adresses de clients comprises entre 192.168.0.1 et 192.168.0.253, en prétendant être la passerelle et le serveur DNS.
On peut utiliser proto.arp_responder pour servir 192.168.0.254 (ou toute autre adresse IP) avec ARP.
Il y a un certain nombre d'options que l'on peut configurer:
| Option | Description |
|---|---|
| network | Sous-réseau pour attribuer les adresses, par exemple, «192.168.0.0/24» ou «10.0.0.0/255.0.0.0» |
| first | Première adresse du sous-réseau à utiliser (256 correspond à x.x.1.0 dans un /16). |
| last | Dernière adresse du sous-réseau à utiliser (258 correspond à x.x.1.2 dans un /16). Si 'None', est utilisé pour le reste de la plage valide. |
| count | Autre moyen de spécifier la dernière adresse à utiliser |
| ip | IP à utiliser pour le serveur DHCP |
| router | Routeur IP pour informer les clients. La valeur par défaut est celle définie pour ip. “None” empêchera le serveur de dire quoi que ce soit aux clients. |
| dns | Serveur DNS pour informer les clients. La valeur par défaut est celle définie pour le router . “None” empêchera le serveur de dire quoi que ce soit aux clients. |
Exemple:
proto.dhcpd --network=10.1.1.0/24 --ip=10.1.1.1 --first=10 --last=None --router=None --dns=4.2.2.1
On peut également lancer ce composant sous le nom proto.dhcpd:default pour servir 192.168.0.100-199.
Juste avant d'émettre une adresse, le serveur DHCP déclenche un événement DHCPLease que l'on peut écouter pour apprendre ou refuser les attributions d'adresses:
def _I_hate_00_00_00_00_00_03 (event):
if event.host_mac == EthAddr("00:00:00:00:00:03"):
event.nak() # Deny it!
core.DHCPD.addListenerByName('DHCPLease', _I_hate_00_00_00_00_00_03)
misc
| POX | POX-1.3 |
|---|---|
| cbench.py | cbench.py |
| full_payload.py | full_payload.py |
| gephi_topo.py | gephi_topo.py |
| ip_loadbalancer.py | ip_loadbalancer.py |
| mac_blocker.py | mac_blocker.py |
| nat.py | nat.py |
| of_tutorial.py | of_tutorial.py |
| pidfile.py | pidfile.py |
misc.of_tutorial
Ce composant est destiné à être utilisé avec le tutoriel OpenFlow . Il agit comme un simple concentrateur, mais peut être modifié pour agir comme un commutateur d'apprentissage L2.
misc.full_payload
Par défaut, lorsqu'un paquet manque la table d'un commutateur, celui-ci ne peut envoyer qu'une partie du paquet (les 128 premiers octets) au contrôleur. Ce composant reconfigure tous les commutateurs qui se connectent pour envoyer le paquet complet.
misc.mac_blocker
Ce composant est destiné à être utilisé avec d’autres applications de transfert réactif, telles que l2_learning et l2_pairs. Il ouvre une interface graphique basée sur Tkinter qui permet de bloquer les adresses MAC.
Cela fonctionne en bloquant son propre gestionnaire PacketIn devant le gestionnaire PacketIn du composant de transfert. Quand il veut bloquer quelque chose, il tue l'événement en renvoyant EventHalt. Ainsi, le composant de transmission ne voit jamais le paquet/événement, ne configure jamais de flux et le trafic meurt.
Ainsi, il présente les interfaces graphiques basées sur Tkinter dans POX, ainsi que la gestion d’événements légèrement avancée (utilisation de gestionnaires d’événements de priorité supérieure pour bloquer PacketIns).
misc.nat
Un composant qui fait la traduction d'adresse réseau.
Paramètres de ligne de commande requis:
| Nom | Description |
|---|---|
| –dpid | Le DPID du commutateur |
| –out-outside-port=X | Le port d'entrée du commutateur (par exemple, “eth0”) |
Paramètres optionnels:
| Nom | Description |
|---|---|
| –subnet=X | Sous-réseau local à utiliser (par exemple, “192.168.0.1/24”) |
| –inside-ip=X | Adresse IP interne que le commutateur prétendra être |
Pour que cela fonctionne avec Open vSwitch, il faudra probablement désactiver OVS contrôle in-band comme ceci:
ovs-vsctl set bridge s1 other-config:disable-in-band=true
misc.ip_loadbalancer
Ce équilibreur de charge TCP simple.
$ ./pox.py misc.ip_loadbalancer --ip=<Service IP> --servers=<Server1 IP>,<Server2 IP>,... [--dpid=<dpid>]
Fournir un service_ip et une liste d'adresses IP du serveur. Les nouveaux flux TCP vers l'adresse IP du service seront redirigés de manière aléatoire vers l'une des adresses IP du serveur.
Les serveurs sont périodiquement interrogés pour savoir s'ils sont en vie en leur envoyant des ARP.
Par défaut, le premier commutateur qui se connecte à un équilibreur de charge est ignoré et les autres commutateurs sont ignorés. Pour une topologie avec plusieurs commutateurs, il est plus logique de spécifier lequel doit être l'équilibreur de charge, ce qui peut être fait avec l'option --dpid sur la ligne de commande. Dans ce cas, pour que les autres commutateurs fassent quelque chose de valable (comme du trafic en aval) on peut utiliser un composant simple faisant la même chose que forwarding.l2_learning sur tous les commutateurs en dehors de l'équilibreur de charge, comme celui-ci:
"""
More or less just l2_learning except it ignores a particular switch
"""
from pox.core import core
from pox.lib.util import str_to_dpid
from pox.forwarding.l2_learning import LearningSwitch
def launch (ignore_dpid):
ignore_dpid = str_to_dpid(ignore_dpid)
def _handle_ConnectionUp (event):
if event.dpid != ignore_dpid:
core.getLogger().info("Connection %s" % (event.connection,))
LearningSwitch(event.connection, False)
core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
misc.gephi_topo
Gephi est permet la visualisation / manipulation / analyse de graphes open source et multiplateforme. Il dispose d'un plugin pour la transmission en continu de graphiques entre eux et quelque chose d'autre via une connexion réseau. Le composant gephi_topo utilise pour fournir une visualisation des commutateurs, des liens et (éventuellement) des hôtes détectés par d'autres composants POX.
Ce composant est basé sur le module tinytopo. Il nécessite discovery et host_tracker est facultatif:
./pox.py openflow.discovery misc.gephi_topo host_tracker forwarding.l2_learning
tk
Ce composant est conçu pour vous aider à créer des interfaces graphiques basées sur Tk dans POX, y compris des boîtes de dialogue simples.
host_tracker
Ce composant tente de suivre les hôtes du réseau - leur emplacement et leur configuration (au moins leurs adresses MAC/IP). Lorsque les choses changent, le composant lève un HostEvent.
Pour un exemple d'utilisation de host_tracker, voir le composant misc.gephi_topo.
En bref, host_tracker fonctionne en examinant les messages entrant dans les paquets et en apprenant les liaisons MAC et IP de cette manière. Eensuite périodiquement des ARP-ping sont eémis pour voir si les hôtes sont toujours là. C cela signifie que les paquets arrivant au contrôleur sont acheminés. Le transfert doit donc être effectué de manière relativement réactive (comme avec forwarding.l2_learning), ou on doit installer des entrées de flux supplémentaires pour que les paquets soient acheminés vers le contrôleur.
On peut définir divers délais d'attente (en secondes) à partir de la ligne de commande:
| Nom | Défaut | Description |
|---|---|---|
| arpAware | 60 * 2 | Les entrées qui répondent à ARP en mode silencieux sont envoyées après cette opération. |
| arpSilent | 60 * 20 | Ceci est pour les entrées silencieuses non connues pour répondre à ARP |
| arpReply | 4 | Temps d'attente pour une réponse ARP avant le nouvel essai |
| timerInterval | 5 | Secondes entre les activations de la minuterie |
| entryMove | 60 | Temps minimum prévu pour déplacer une entrée physique |
Bonnes valeurs pour les tests:
--arpAware=15 --arpSilent=45 --arpReply=1 --entryMove=4
On peut également spécifier le nombre de pings ARP avant de décider que cela a échoué:
--pingLim=2
datapaths
| POX | POX-1.3 |
|---|---|
| ctl.py | ctl.py |
| nx_switch.py | nx_switch.py |
| pcap_switch.py | pcap_switch.py |
| switch.py | switch.py |
datapaths.pcap_switch
Ce composant implémente le côté commutateur d’OpenFlow - en créant un commutateur OpenFlow pouvant se connecter à un contrôleur OpenFlow (qui pourrait être la même instance de POX, une autre instance de POX ou tout autre contrôleur OpenFlow!) Et transmettre des paquets.
Il est basé sur une superclasse un peu plus abstraite qui peut être utilisée pour implémenter le côté commutateur d’OpenFlow sans transférer les paquets - par exemple, pour fournir un commutateur «virtuel» OpenFlow (inspiré de FlowVisor), pour fournir uniquement l’interface OpenFlow au-dessus. Ceci est également utile pour le prototypage d'extensions OpenFlow ou pour le débogage (il est relativement facile de le modifier pour simuler des conditions qui génèrent des erreurs dans les contrôleurs, par exemple). Ce n'est pas censé être un commutateur de production - la performance n'est pas particulièrement bonne!
log
POX utilise le système de journalisation de Python, et le module de log permet de configurer une bonne partie de cela via la ligne de commande. Par exemple, onpeut envoyer le journal dans un fichier, modifier le format des messages du journal pour inclure la date, etc.
Désactiver le journal de la console
On peut désactiver le journal «normal» de POX en utilisant:
$ ./pox.py log --no-default
Formatage du journal
On peut utiliser les attributs LogRecord de Python pour formater des journaux. Comme dans l'exemple suivant, pour ajouter des horodatages au journal:
$ ./pox.py log --format="%(asctime)s: %(message)s"
Ou avec des horodatages plus simples:
./pox.py log --format="[%(asctime)s] %(message)s" --datefmt="%H:%M:%S"
Journal de sortie
Les messages de journal sont traités par différents gestionnaires qui les affichent à l'écran, les enregistrent dans un fichier, les envoient via le réseau, etc. On peut écrire un journal, mais Python est également livré avec plusieurs, qui sont documentés dans la Référence Python pour logging.handlers. POX permet de configurer de nombreux gestionnaires intégrés à Python à partir de la ligne de commande. POX vous permet de configurer:
| Nom | Type |
|---|---|
| stderr | StreamHandler pour le flux stderr |
| stdout | StreamHandler pour le flux stdout |
| File | FileHandler pour le fichier nommé |
| WatchedFile | WatchedFileHandler |
| RotatingFile | RotatingFileHandler |
| TimedRotatingFile | TimedRotatingFileHandler |
| Socket | SocketHandler - Envoie à la socket TCP |
| Datagram | DatagramHandler - Envoie sur UDP |
| SysLog | SysLogHandler - Sorties vers le service syslog |
| HTTP | HTTPHandler - Sortie sur un serveur Web via GET ou POST |
Pour les utiliser, spécifier simplement le nom, suivi d'une liste des arguments de position séparés par des virgules pour le type de gestionnaire. Par exemple, FileHandler prend un nom de fichier, et éventuellement un mode d'ouverture (qui est par défaut append):
$ ./pox.py log --file=pox.log
Ou si on veut écraser le fichier à chaque fois:
./pox.py log --file=pox.log,w
On peut également utiliser des arguments nommés en faisant précéder l'entrée par un *, puis en utilisant une liste de paires clé=valeur séparées par des virgules. Par exemple:
./pox.py log --*TimedRotatingFile=filename=foo.log,when=D,backupCount=5
log.color
Le module log.color colorise le journal lorsque cela est possible. C’est en fait assez agréable, mais pour en tirer le meilleur parti, il faut un peu plus de configuration (cf samples.pretty_log).
log.level
POX utilise l'infrastructure de journalisation de Python. Différents composants ont chacun leurs propres enregistreurs, dont le nom est affiché dans le message de journal. Les enregistreurs forment en réalité une hiérarchie -on peut avoir un enregistreur «foo» avec un sous-enregistreur «bar», qui ensemble serait appelé «foo.bar». De plus, chaque message de journal est associé à un «niveau» qui correspond à l'importance (ou à la gravité) du message. Le composant log.level permet de configurer quels enregistreurs affichent quel niveau de détail. Les niveaux de log du plus grave au moins grave sont:
| CRITICAL |
| ERROR |
| WARNING |
| INFO |
| DEBUG |
Le niveau par défaut de POX est INFO. Pour définir une valeur par défaut différente (par exemple, un niveau différent pour la “racine” de la hiérarchie du consignateur):
$ ./pox.py log.level --WARNING
Lorsqu'on veut activer la verbosité des journaux liés à OpenFlow pour résoudre un problème, on peut ajuster tous les messages de journal liés à OpenFlow de la manière suivante:
./pox.py log.level --WARNING --openflow=DEBUG
Si cela laisse trop de messages de niveau DEBUG provenant d'openflow.discovery qui n' intéressent pas, on peut alors le désactiver spécifiquement:
./pox.py log.level --WARNING --openflow=DEBUG --openflow.discovery=INFO
samples.pretty_log
Ce module simple utilise log.color et un format de journal personnalisé pour fournir une sortie de journal fonctionnelle et agréable sur la console.
