Write in front
The experimental reference
- The pox script sets the controller's forwarding policy, so just understand the script.
- The Mininet script sets up the topology and related information, so just understand the script as well.
- Pox scripts are not understood at the moment.
- This experiment I learned: Pox controller Web interface, the first time really see the flow table entries.
Experimental topology
- In this environment, assuming H1 Ping H4, the initial routing rule is s1-s2-s5, after one second, the routing forwarding rule becomes s1-s3-s5, and then one second, the rule becomes s1-s4-s5, and then back to the original forwarding rule s1-s2-s5. This cyclic scheduling example dynamically changes the forwarding rules of the switch.
Experiment Step 1: Build the environment
- A virtual machine with mininet installed.
- A virtual machine with pox installed.
2. Create a script
- Create a new file lab_controller.py the/pox directory and edit its contents:
From Pox.core import Coreimport pox.openflow.libopenflow_01 as Offrom pox.lib.util import Dpidtostrfrom Pox.lib.addresses import ipaddr, ethaddrfrom pox.lib.packet.arp import arpfrom pox.lib.packet.ethernet import Ethernet, Ether_broadcastfrom pox.lib.packet.packet_base Import packet_basefrom pox.lib.packet.packet_utils import *import Pox.lib.packet as Pktfrom pox.lib.recoco import timerimport timelog = Core.getlogger () s1_dpid=0s2_dpid=0s3_dpid=0s4_ dpid=0s5_dpid=0s1_p1=0s1_p4=0s1_p5=0s1_p6=0s2_p1=0s3_p1=0s4_p1=0pre_s1_p1=0pre_s1_p4=0pre_s1_p5=0pre_s1_p6= 0pre_s2_p1=0pre_s3_p1=0pre_s4_p1=0turn=0def getthetime (): #fuction to create a timestamp flock = Time.localtime () Then = "[%s-%s-%s"% (str (flock.tm_year), str (flock.tm_mon), str (flock.tm_mday)) if int (flock.tm_hour) <10:hrs = "0%s"% (s TR (flock.tm_hour)) else:hrs = str (flock.tm_hour) if int (flock.tm_min) <10:mins = str (flock.tm_min) secs = " 0%s "% (str (flock.tm_sec)) Else:secs = str (flock.tm_sec) then + ="]%s.%s.%s "% (hrs,mins,secs) return thendef _timer_func (): Global S1_dpid, S2_dpid, S3_dpid, S4_dpid, S5_dpid,turn #print Getthetime (), "sent the port stats request to S1_dpid" If turn==0:msg = Of.ofp_flow_mod () msg.command=of. Ofpfc_modify_strict msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 Msg.match.dl_type = 0x 0800 MSG.MATCH.NW_DST = "10.0.0.4" Msg.actions.append (of.ofp_action_output (port = 5)) Core.openflow.getConn Ection (s1_dpid). Send (msg) turn=1 return if turn==1:msg = Of.ofp_flow_mod () msg.command=of. Ofpfc_modify_strict msg.priority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 Msg.match.dl_type = 0x 0800 MSG.MATCH.NW_DST = "10.0.0.4" Msg.actions.append (of.ofp_action_output (port = 6)) Core.openflow.getConn Ection (s1_dpid). Send (msg) turn=2 return if turn==2:msg = Of.ofp_flow_mod () msg.command=of. Ofpfc_modify_strict msg.priority =100Msg.idle_timeout = 0 Msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" msg . Actions.append (Of.ofp_action_output (port = 4)) turn=0 Returndef _handle_portstats_received (event): Global s1_ P1,S1_P4, S1_P5, S1_P6, S2_p1, S3_P1, S4_P1 Global PRE_S1_P1,PRE_S1_P4, PRE_S1_P5, PRE_S1_P6, Pre_s2_p1, PRE_S3_P1, pre_s 4_p1 if event.connection.dpid==s1_dpid:for f in event.stats:if Int (f.port_no) <65534:if f.port_no==1: Pre_s1_p1=s1_p1 s1_p1=f.rx_packets if F.port_no==4:pre_s1_p4=s1_p4 s1_p4=f.tx _packets #s1_p4 =f.tx_bytes if F.PORT_NO==5:PRE_S1_P5=S1_P5 s1_p5=f.tx_packets if F.port_no==6:pre_s1_p6=s1_p6 s1_p6=f.tx_packets for F in event.stats:if Int (f.port_no) <6 5534:if f.port_no==1:pre_s2_p1=s2_p1 s2_p1=f.rx_packets #s2_p1 =f.rx_bytes if even T.connection.dpid==s3_dpId:for f in Event.stats:if Int (f.port_no) <65534:if F.PORT_NO==1:PRE_S3_P1=S3_P1 S3_p1=f.rx_packets if event.connection.dpid==s4_dpid:for f in event.stats:if Int (f.port_no) <65534: If F.PORT_NO==1:PRE_S4_P1=S4_P1 s4_p1=f.rx_packetsdef _handle_connectionup (event): Global S1_DP ID, S2_dpid, s3_dpid, S4_dpid, s5_dpid print "Connectionup:", Dpidtostr (event.connection.dpid) #remember the connection Dpid for switch to M in event.connection.features.ports:if m.name = = "S1-eth1": S1_dpid = Event.connection.dpid Print "s1_dpid=", s1_dpid elif m.name = = "S2-eth1": S2_dpid = event.connection.dpid print "s2_dpid=", s 2_dpid elif M.name = = "S3-eth1": s3_dpid = event.connection.dpid elif M.name = = "S4-eth1": S4_dpid = Event . connection.dpid print "s4_dpid=", s4_dpid elif m.name = = "S5-eth1": s5_dpid = event.connection.dpid pri NT "S5_dpid=", S5_dpidIf S1_dpid<>0 and S2_dpid<>0 and S3_dpid<>0 and S4_dpid<>0:timer (1, _timer_func, Recurring=Tru e) def _handle_packetin (event): Global S1_dpid, S2_dpid, S3_dpid, S4_dpid, s5_dpid packet=event.parsed if Event.connecti On.dpid==s1_dpid:a=packet.find (' ARP ') if A and a.protodst== "10.0.0.4": Msg = Of.ofp_packet_out (DATA=EVENT.O FP) msg.actions.append (Of.ofp_action_output (port=4)) Event.connection.send (msg) If A and a.protodst== "10.0 .0.5 ": msg = of.ofp_packet_out (DATA=EVENT.OFP) msg.actions.append (Of.ofp_action_output (port=5)) event.co Nnection.send (msg) If A and a.protodst== "10.0.0.6": Msg = of.ofp_packet_out (DATA=EVENT.OFP) Msg.actions.ap Pend (Of.ofp_action_output (port=6)) Event.connection.send (msg) If A and a.protodst== "10.0.0.1": Msg = Of.of P_packet_out (DATA=EVENT.OFP) msg.actions.append (Of.ofp_action_output (port=1)) event.connection.send (msg) i f A and a.protodst== "10.0.0.2 ": msg = of.ofp_packet_out (DATA=EVENT.OFP) msg.actions.append (Of.ofp_action_output (port=2)) event.c Onnection.send (msg) If A and a.protodst== "10.0.0.3": Msg = of.ofp_packet_out (DATA=EVENT.OFP) MSG.ACTIONS.A Ppend (Of.ofp_action_output (port=3)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 Msg.idle_timeout = 0 Msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" Msg.ac Tions.append (of.ofp_action_output (port = 1)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority = Msg.idle_timeout = 0 Msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" Msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.pri ority =100 msg.idle_timeout = 0 msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0 .3 "Msg.actions.append (of.ofp_action_output (port = 3)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 ms G.idle_timeout = 0 Msg.hard_timeout = 1 Msg.match.dl_type = 0x0800 MSG.MATCH.NW_DST = "10.0.0.4" Msg.actio Ns.append (of.ofp_action_output (port = 4)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 Msg.idle_timeout = 0 Msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.5" ms G.actions.append (of.ofp_action_output (port = 5)) Event.connection.send (msg) msg = Of.ofp_flow_mod () Msg.priori Ty =100 msg.idle_timeout = 0 msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.6" Msg.actions.append (of.ofp_action_output (port = 6)) event.connection.send (msg) elif event.connection.dpid==s2_dpi D:msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 Msg.match.in_por t = 1 msg.match.dl_type=0x0806 Msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type= 0x0800 Msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x08 Msg.actions.append (of.ofp_action_output (port = 1)) Event.connection.send (msg) msg = Of.ofp_flow_mod () m sg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0800 Msg.actions.append (of.ofp_action_output (port = 1)) event.connection.send (msg) elif Event.connection.dpid==s3_dpid: msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 Msg.match.dl_type=0x0806 Msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x 0800 msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0806 Msg.actions.append (of.ofp_action_output (port = 1)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg . Priority =10 Msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0800 Msg.actions.append (of.ofp_action_output (port = 1)) event.connection.send (msg) elif Event.connection.dpid==s4_dpid: msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 Msg.match.in_port = 1 msg.match.dl_type=0x0806 Msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 1 msg.match.dl_type=0x08 XX msg.actions.append (of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () m sg.priority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0806 Msg.actions.append (of.ofp_action_output (port = 1)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.p riority =10 msg.idle_timeout = 0 msg.hard_timeout = 0 msg.match.in_port = 2 msg.match.dl_type=0x0800 m Sg.actions.append (of.ofp_action_output (port = 1)) event.connection.send (msg) elif Event.connection.dpid==s5_dpid: A=packet.find (' ARP ') if A and a.protodst== "10.0.0.4": Msg = of.ofp_packet_out (DATA=EVENT.OFP) msg.actions . Append (Of.ofp_action_ouTput (port=4)) Event.connection.send (msg) If A and a.protodst== "10.0.0.5": Msg = Of.ofp_packet_out (data=eve NT.OFP) Msg.actions.append (Of.ofp_action_output (port=5)) Event.connection.send (msg) If A and a.protodst== " 10.0.0.6 ": msg = of.ofp_packet_out (DATA=EVENT.OFP) msg.actions.append (Of.ofp_action_output (port=6)) even T.connection.send (msg) If A and a.protodst== "10.0.0.1": Msg = of.ofp_packet_out (DATA=EVENT.OFP) msg.action S.append (Of.ofp_action_output (port=1)) Event.connection.send (msg) If A and a.protodst== "10.0.0.2": Msg = O F.ofp_packet_out (DATA=EVENT.OFP) msg.actions.append (Of.ofp_action_output (port=2)) Event.connection.send (msg) If A and a.protodst== "10.0.0.3": Msg = of.ofp_packet_out (DATA=EVENT.OFP) msg.actions.append (of.ofp_action_o Utput (port=3)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 msg.idle_timeout = 0 Msg.hard_timeout =0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.1" Msg.actions.append (of.ofp_action_output (port = 1)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 msg.idle_timeout = 0 Msg.hard_tim Eout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.2" Msg.actions.append (Of.ofp_action_output (port = 2)) event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 msg.idle_timeout = 0 msg.h Ard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.3" Msg.actions.append (OF.OFP_ACTION_OUTP UT (port = 3)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 msg.idle_timeout = 0 Msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.4" Msg.actions.append (of.ofp_acti On_output (port = 4)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 msg.idle_timeout = 0 Msg.hard_timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.5" Msg.actions.append (of.ofp_action_output (port = 5)) Event.connection.send (msg) msg = Of.ofp_flow_mod () msg.priority =100 msg.idle_timeout = 0 Msg.hard _timeout = 0 Msg.match.dl_type = 0x0800 msg.match.nw_dst = "10.0.0.6" Msg.actions.append (Of.ofp_action_output ( Port = 6)) Event.connection.send (msg) def launch (): Global start_time core.openflow.addListenerByName ("Portstatsrece Ived ", _handle_portstats_received) core.openflow.addListenerByName (" Connectionup ", _handle_connectionup) Core.openflow.addListenerByName ("Packetin", _handle_packetin)
- The script implements a dynamic forwarding policy.
- I guess the basic idea is to give the switch S1 a stream table entry based on time. The
- creates the file mymininet.py in Mininet. Edit its contents as:
#!/usr/bin/python from Mininet.topo import topofrom mininet.net import mininetfrom mininet.node Import Cpulimitedhostfrom mininet.link Import tclinkfrom mininet.util import dumpnodeconnectionsfrom mininet.log Import Setloglevelfrom mininet.node import Controller from mininet.cli import clifrom functools import Partialfrom Mininet.node i Mport Remotecontrollerimport OS class Mytopo (Topo): "Single switch connected to n hosts." def __init__ (self): topo.__init__ (self) s1=self.addswitch (' s1 ') s2=self.addswitch (' s2 ') S3=sel F.addswitch (' S3 ') S4=self.addswitch (' S4 ') S5=self.addswitch (' S5 ') h1=self.addhost (' H1 ') h2=se Lf.addhost (' H2 ') h3=self.addhost (' H3 ') h4=self.addhost (' H4 ') h5=self.addhost (' h5 ') h6=self.add Host (' h6 ') Self.addlink (H1, S1, bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, use_htb=true) self . Addlink (H2, S1, bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=true) Self.addlink (H3, S1, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=true) self.addlink (S1, S2, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=true) Self.addlink (S1, S3, Bw=1, delay= ' 10ms ', loss=0, M ax_queue_size=1000, Use_htb=true) Self.addlink (S1, S4, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=Tr UE) Self.addlink (S2, S5, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=true) Self.addlink (S3, S 5, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=true) Self.addlink (S4, S5, Bw=1, delay= ' 10ms ', loss=0 , max_queue_size=1000, Use_htb=true) Self.addlink (S5, H4, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, USE_HTB =true) Self.addlink (S5, H5, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, Use_htb=true) Self.addlink (S5 , H6, Bw=1, delay= ' 10ms ', loss=0, max_queue_size=1000, use_htb=true) def perftest (): "Create Network and run simple PE Rformance Test "topo= Mytopo () net = Mininet (Topo=topo, Host=cpulimitedhost, Link=tclink, Controller=partial (Remotecontroller, ip= ' 10.0.0. (port=6633)) Net.start () print "Dumping host connections" dumpnodeconnections (net.hosts) H1,h2,h3=net.get ( ' H1 ', ' H2 ', ' H3 ') h4,h5,h6=net.get (' H4 ', ' H5 ', ' H6 ') H1.setmac ("0:0:0:0:0:1") H2.setmac ("0:0:0:0:0:2") H3.setmac (" 0:0:0:0:0:3 ") H4.setmac (" 0:0:0:0:0:4 ") H5.setmac (" 0:0:0:0:0:5 ") H6.setmac (" 0:0:0:0:0:6 ") CLI (net) net.stop ( if __name__ = = ' __main__ ': setloglevel (' info ') perftest ()
- The script sets up the topology. basically understandable.
3. Run the script
- Run script under/pox directory lab_controller.py
./pox.py lab_controller
- Run the script under Mininet mymininet.py
chmod +x mymininet.py./mymininet.py
- Mininet Terminal information
- Pox Controller Terminal Information
- Now we pass the H1 to H4 to detect the dynamic forwarding function.
- In the Mininet terminal input:
h1 ping -i 0.1 h4 #h1每秒向h4发10个包
- At this time in the Pox interface does not appear useful information, but is some warning information.
4. Solution
- Since I can't see the details of the delivery in the terminal, I think of the Web interface. Other controllers have UI interface pox should have it, too?
- I found the Pox UI interface implemented in a blog post: Poxdesk.
Reference Blog
- To use Poxdesk when you run the Pox script, you must add some additional parameters, and for this experiment run lab_controller.py, the command is as follows:
./pox.py lab_controller web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk
./pox.py 要运行的脚本 web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk
- In the browser, enter: Http://pox-ip:8000/poxdesk to access the interface, where Pox-ip is the native IP address.
- After entering the Web interface, we open the S1 flowtable window. It can be found that the output port in action switches between 5 and 6 for a periodic change in the flow table entry for the purpose of 10.0.0.4 (host H4). But no 4 (switch s2), this problem is not resolved, it may be the problem of the script itself.
5. Specific Connection diagram
- The details of the topology can be obtained through the net command in Mininet, and I have simply drawn an easy to understand:
There is a problem
- Why can't I switch to S2 when the port is switched?
Experiment on dynamic change of forwarding rules in mininet experiment