blob: 508b0760591778fc4f078e4a67255c7375e93343 [file] [log] [blame]
Dan Talaycof75360a2010-02-05 22:22:54 -08001"""This module simulates the network.
2
3Copyright(C) 2009, Stanford University
4Date November 2009
5Created by ykk
6"""
7import openflow
8import output
9import of.msg
10import of.network
11
12class network(of.network.network):
13 """Class to simulate OpenFlow network
14
15 Copyright(C) 2009, Stanford University
16 Date November 2009
17 Created by ykk
18 """
19 def __init__(self):
20 """Initialize network
21 """
22 of.network.network.__init__(self)
23 ##Name of use for output
24 self.name = self.__class__.__name__+str(id(self))
25
26class link(of.network.link):
27 """Class to simulate link
28
29 Copyright(C) 2009, Stanford University
30 Date November 2009
31 Created by ykk
32 """
33 def __init__(self, switch1, switch2, isUp=True):
34 """Initialize link
35 """
36 of.network.link.__init__(self, switch1, switch2)
37 ##Name of use for output
38 self.name = self.__class__.__name__+str(id(self))
39 ##Indicate if link is up
40 self.isUp = isUp
41
42class switch(of.network.switch):
43 """Class to simulate OpenFlow switch
44
45 Copyright(C) 2009, Stanford University
46 Date November 2009
47 Created by ykk
48 """
49 def __init__(self, messages, controller, port, miss_send_len=128,
50 dpid=None, n_buffers=100, n_tables=1,
51 capability=None, parser=None, connection=None):
52 """Initialize switch
53 """
54 of.network.switch.__init__(self, miss_send_len,
55 None, dpid, n_buffers, n_tables,
56 capability)
57 ##Name of use for output
58 self.name = self.__class__.__name__+str(id(self))
59 ##Reference to OpenFlow messages
60 self.__messages = messages
61 ##Reference to connection
62 self.connection = openflow.tcpsocket(messages, controller, port)
63 self.sock = self.connection.sock
64 ##Reference to Parser
65 self.parser = None
66 if (parser == None):
67 self.parser = of.msg.parser(messages)
68 else:
69 self.parser = parser
70
71 def receive_openflow(self, packet):
72 """Switch receive OpenFlow packet, and respond accordingly
73 """
74 dic = self.__messages.peek_from_front("ofp_header", packet)
75 if (dic["type"][0] == self.__messages.get_value("OFPT_HELLO")):
76 output.dbg("Receive hello", self.name)
77 elif (dic["type"][0] == self.__messages.get_value("OFPT_ECHO_REQUEST")):
78 self.reply_echo(dic["xid"][0])
79 elif (dic["type"][0] == self.__messages.get_value("OFPT_FEATURES_REQUEST")):
80 self.reply_features(dic["xid"][0])
81 elif (dic["type"][0] == self.__messages.get_value("OFPT_FLOW_MOD")):
82 self.handle_flow_mod(packet)
83 else:
84 output.dbg("Unprocessed message "+self.parser.header_describe(dic),
85 self.name)
86
87 def send_hello(self):
88 """Send hello
89 """
90 self.connection.structsend("ofp_hello",
91 0, self.__messages.get_value("OFPT_HELLO"),
92 0, 0)
93 output.dbg("Send hello",self.name)
94
95 def send_packet(self, inport, bufferid=None, packet="", xid=0, reason=None):
96 """Send packet in
97 Assume no match as reason, bufferid = 0xFFFFFFFF,
98 and empty packet by default
99 """
100 if (reason == None):
101 reason = self.__messages.get_value("OFPR_NO_MATCH")
102 if (bufferid == None):
103 bufferid = int("0xFFFFFFFF",16)
104 pktin = self.__messages.pack("ofp_packet_in",
105 0, self.__messages.get_value("OFPT_PACKET_IN"),
106 0, xid, #header
107 bufferid, len(packet),
108 inport, reason, 0)
109 self.connection.structsend_raw(pktin+packet)
110 output.dbg("Send packet ",self.name)
111
112 def send_echo(self, xid=0):
113 """Send echo
114 """
115 self.connection.structsend_xid("ofp_header",
116 0, self.__messages.get_value("OFPT_ECHO_REQUEST"),
117 0, xid)
118 output.dbg("Send echo", self.name)
119
120 def reply_echo(self, xid):
121 """Reply to echo request
122 """
123 self.connection.structsend_xid("ofp_header",
124 0, self.__messages.get_value("OFPT_ECHO_REPLY"),
125 0, xid)
126 output.dbg("Reply echo of xid:"+str(xid),self.name)
127
128 def reply_features(self, xid):
129 """Reply to feature request
130 """
131 self.connection.structsend_xid("ofp_switch_features",
132 0, self.__messages.get_value("OFPT_FEATURES_REPLY"),
133 0, xid,
134 self.datapath_id, self.n_buffers,
135 self.n_tables,0,0,0,
136 self.capability.get_capability(self.__messages),
137 self.capability.get_actions(self.__messages))
138 output.dbg("Replied features request of xid "+str(xid), self.name)
139
140 def handle_flow_mod(self, packet):
141 """Handle flow mod: just print it here
142 """
143 output.dbg(self.parser.flow_mod_describe(packet), self.name)
144