blob: 252fb8ce325141e38d6fed4be737b2b95bcde93b [file] [log] [blame]
adminbae64d82013-08-01 10:50:15 -07001#/usr/bin/env python
kelvin8ec71442015-01-15 16:57:00 -08002"""
adminbae64d82013-08-01 10:50:15 -07003Created on 26-Nov-2012
kelvin8ec71442015-01-15 16:57:00 -08004
5author:: Raghav Kashyap( raghavkashyap@paxterrasolutions.com )
adminbae64d82013-08-01 10:50:15 -07006
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
kelvin8ec71442015-01-15 16:57:00 -080011 ( at your option ) any later version.
adminbae64d82013-08-01 10:50:15 -070012
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
kelvin8ec71442015-01-15 16:57:00 -080019 along with TestON. If not, see <http://www.gnu.org/licenses/>.
adminbae64d82013-08-01 10:50:15 -070020
21
22
23DPCTL driver class provides the basic functions of DPCTL controller
kelvin8ec71442015-01-15 16:57:00 -080024"""
adminbae64d82013-08-01 10:50:15 -070025import pexpect
kelvin8ec71442015-01-15 16:57:00 -080026import struct
27import fcntl
28import os
29import sys
30import signal
adminbae64d82013-08-01 10:50:15 -070031import sys
32from drivers.common.cli.toolsdriver import Tools
33import pydoc
34from drivers.common.clidriver import CLI
35import re
36import os
37import sys
38
kelvin8ec71442015-01-15 16:57:00 -080039
40class DpctlCliDriver( Tools ):
41
42 """
adminbae64d82013-08-01 10:50:15 -070043 DpctlCliDriver driver class provides the basic functions of DPCTL controller
kelvin8ec71442015-01-15 16:57:00 -080044 """
45 def __init__( self ):
46 super( DpctlCliDriver, self ).__init__()
adminbae64d82013-08-01 10:50:15 -070047 self.handle = self
kelvin8ec71442015-01-15 16:57:00 -080048 self.wrapped = sys.modules[ __name__ ]
49
50 def connect( self, **connectargs ):
51
adminbae64d82013-08-01 10:50:15 -070052 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080053 vars( self )[ key ] = connectargs[ key ]
adminbae64d82013-08-01 10:50:15 -070054
kelvin8ec71442015-01-15 16:57:00 -080055 self.name = self.options[ 'name' ]
56
57 self.handle = super(
58 DpctlCliDriver, self ).connect( user_name=self.user_name,
59 ip_address=self.ip_address,
60 port=None,
61 pwd=self.pwd )
62 if self.handle:
63 main.log.info( "Connected to the host" )
64 return main.TRUE
65 else:
66 main.log.error(
67 "Connection failed to the host " +
68 self.user_name +
69 "@" +
70 self.ip_address )
71 return main.FALSE
72
73 def addFlow( self, **flowParameters ):
74 """
adminbae64d82013-08-01 10:50:15 -070075 addFlow create a new flow entry into flow table using "dpctl"
kelvin8ec71442015-01-15 16:57:00 -080076 """
77 args = utilities.parse_args( [
78 "TCPIP",
79 "TCPPORT",
80 "INPORT",
81 "ACTION",
82 "TIMEOUT" ],
83 **flowParameters )
84
adminbae64d82013-08-01 10:50:15 -070085 cmd = "dpctl add-flow tcp:"
kelvin8ec71442015-01-15 16:57:00 -080086 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
87 tcpPort = args[ "TCPPORT" ] if args[
88 "TCPPORT" ] is not None else "6634"
89 timeOut = args[ "TIMEOUT" ] if args[ "TIMEOUT" ] is not None else 120
90 cmd = cmd + tcpIP + ":" + tcpPort + " in_port=" + \
91 str( args[ "INPORT" ] ) + ",idle_timeout=" + str(
92 args[ "TIMEOUT" ] ) + ",actions=" + args[ "ACTION" ]
93 response = self.execute( cmd=cmd, prompt="\~\$", timeout=60 )
94 if utilities.assert_matches( expect="openflow", actual=response, onpass="Flow Added Successfully", onfail="Adding Flow Failed!!!" ):
adminbae64d82013-08-01 10:50:15 -070095 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -080096 else:
adminbae64d82013-08-01 10:50:15 -070097 return main.FALSE
98
kelvin8ec71442015-01-15 16:57:00 -080099 def showFlow( self, **flowParameters ):
100 """
adminbae64d82013-08-01 10:50:15 -0700101 showFlow dumps the flow entries of flow table using "dpctl"
kelvin8ec71442015-01-15 16:57:00 -0800102 """
103 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
104 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
105 tcpPort = args[ "TCPPORT" ] if args[
106 "TCPPORT" ] is not None else "6634"
107 command = "dpctl show tcp:" + str( tcpIP ) + ":" + str( tcpPort )
108 response = self.execute(
109 cmd=command,
110 prompt="get_config_reply",
111 timeout=240 )
112 if utilities.assert_matches( expect='features_reply', actual=response, onpass="Show flow executed", onfail="Show flow execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700113 main.last_result = main.TRUE
114 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800115 else:
adminbae64d82013-08-01 10:50:15 -0700116 main.last_result = main.FALSE
117 return main.FALSE
118
kelvin8ec71442015-01-15 16:57:00 -0800119 def dumpFlow( self, **flowParameters ):
120 """
adminbae64d82013-08-01 10:50:15 -0700121 dumpFlow gives installed flow information
kelvin8ec71442015-01-15 16:57:00 -0800122 """
123 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
124 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
125 tcpPort = args[ "TCPPORT" ] if args[
126 "TCPPORT" ] is not None else "6634"
127 command = "dpctl dump-flows tcp:" + str( tcpIP ) + ":" + str( tcpPort )
128 response = self.execute( cmd=command, prompt="type=", timeout=240 )
129 if utilities.assert_matches( expect='stats_reply', actual=response, onpass="Dump flow executed", onfail="Dump flow execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700130 main.last_result = main.TRUE
131 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800132 else:
adminbae64d82013-08-01 10:50:15 -0700133 main.last_result = main.FALSE
134 return main.FALSE
135
kelvin8ec71442015-01-15 16:57:00 -0800136 def dumpTables( self, **flowParameters ):
137 """
adminbae64d82013-08-01 10:50:15 -0700138 dumpTables gives statistics for each of the flow tables used by datapath switch.
kelvin8ec71442015-01-15 16:57:00 -0800139 """
140 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
141 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
142 tcpPort = args[ "TCPPORT" ] if args[
143 "TCPPORT" ] is not None else "6634"
144 command = "dpctl dump-tables tcp:" + \
145 str( tcpIP ) + ":" + str( tcpPort )
146 response = self.execute( cmd=command, prompt="matched", timeout=240 )
147 if utilities.assert_matches( expect='lookup=3', actual=response, onpass="Dump Tables executed", onfail="Dump Tables execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700148 main.last_result = main.TRUE
149 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800150 else:
adminbae64d82013-08-01 10:50:15 -0700151 main.last_result = main.FALSE
152 return main.FALSE
kelvin8ec71442015-01-15 16:57:00 -0800153
154 def dumpPorts( self, **flowParameters ):
155 """
adminbae64d82013-08-01 10:50:15 -0700156 dumpPorts gives ports information
kelvin8ec71442015-01-15 16:57:00 -0800157 """
158 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
159 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
160 tcpPort = args[ "TCPPORT" ] if args[
161 "TCPPORT" ] is not None else "6634"
162 command = "dpctl dump-ports tcp:" + str( tcpIP ) + ":" + str( tcpPort )
163 response = self.execute( cmd=command, prompt="rx pkts", timeout=240 )
164 if utilities.assert_matches( expect='ports', actual=response, onpass="Dump Ports executed", onfail="Dump Ports execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700165 main.last_result = main.TRUE
166 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800167 else:
adminbae64d82013-08-01 10:50:15 -0700168 main.last_result = main.FALSE
169 return main.FALSE
170
kelvin8ec71442015-01-15 16:57:00 -0800171 def dumpAggregate( self, **flowParameters ):
172 """
adminbae64d82013-08-01 10:50:15 -0700173 dumpAggregate gives installed flow information.ggregate statistics for flows in datapath WITCH's tables that match flows.
174 If flows is omitted, the statistics are aggregated across all flows in the datapath's flow tables
kelvin8ec71442015-01-15 16:57:00 -0800175 """
176 args = utilities.parse_args(
177 [ "TCPIP", "TCPPORT", "FLOW" ], **flowParameters )
178 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
179 tcpPort = args[ "TCPPORT" ] if args[
180 "TCPPORT" ] is not None else "6634"
181 flow = args[ "FLOW" ] if args[ "FLOW" ] is not None else ""
182 command = "dpctl dump-aggregate tcp:" + \
183 str( tcpIP ) + ":" + str( tcpPort ) + " " + str( flow )
184 response = self.execute(
185 cmd=command,
186 prompt="flow_count=",
187 timeout=240 )
188 if utilities.assert_matches( expect='stats_reply', actual=response, onpass="Dump Aggregate executed", onfail="Dump Aggregate execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700189 main.last_result = main.TRUE
190 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800191 else:
adminbae64d82013-08-01 10:50:15 -0700192 main.last_result = main.FALSE
193 return main.FALSE
194
kelvin8ec71442015-01-15 16:57:00 -0800195 def delFlow( self, **flowParameters ):
196 """
adminbae64d82013-08-01 10:50:15 -0700197 delFlow Deletes entries from the datapath switch's tables that match flow
kelvin8ec71442015-01-15 16:57:00 -0800198 """
199 args = utilities.parse_args(
200 [ "TCPIP", "TCPPORT", "FLOW" ], **flowParameters )
201 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
202 tcpPort = args[ "TCPPORT" ] if args[
203 "TCPPORT" ] is not None else "6634"
204 flow = args[ "FLOW" ] if args[ "FLOW" ] is not None else ""
205 command = "dpctl del-flows tcp:" + \
206 str( tcpIP ) + ":" + str( tcpPort ) + " " + str( flow )
207 response = self.execute(
208 cmd=command,
209 prompt="ETH-Tutorial",
210 timeout=240 )
211 if utilities.assert_matches( expect='@', actual=response, onpass="Delete flow executed", onfail="Delete flow execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700212 main.last_result = main.TRUE
213 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800214 else:
adminbae64d82013-08-01 10:50:15 -0700215 main.last_result = main.FALSE
216 return main.FALSE
217
kelvin8ec71442015-01-15 16:57:00 -0800218 def show( self, **flowParameters ):
219 """
adminbae64d82013-08-01 10:50:15 -0700220 show gives information on datapath switch including information on its flow tables and ports.
kelvin8ec71442015-01-15 16:57:00 -0800221 """
222 args = utilities.parse_args( [ "TCPIP", "TCPPORT" ], **flowParameters )
223 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
224 tcpPort = args[ "TCPPORT" ] if args[
225 "TCPPORT" ] is not None else "6634"
226 command = "dpctl show tcp:" + str( tcpIP ) + ":" + str( tcpPort )
227 response = self.execute(
228 cmd=command,
229 prompt="miss_send_len=",
230 timeout=240 )
231 if utilities.assert_matches( expect='get_config_reply', actual=response, onpass="show command executed", onfail="show command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700232 main.last_result = main.TRUE
233 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800234 else:
adminbae64d82013-08-01 10:50:15 -0700235 main.last_result = main.FALSE
236 return main.FALSE
237
kelvin8ec71442015-01-15 16:57:00 -0800238 def showStatus( self, **flowParameters ):
239 """
240 showStatus gives a series of key-value pairs that report the status of switch.
241 If key is specified, only the key-value pairs whose key names begin with key are printed.
242 """
243 args = utilities.parse_args(
244 [ "TCPIP", "TCPPORT", "KEY" ], **flowParameters )
245 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
246 tcpPort = args[ "TCPPORT" ] if args[
247 "TCPPORT" ] is not None else "6634"
248 key = args[ "KEY" ] if args[ "KEY" ] is not None else ""
249 command = "dpctl status tcp:" + \
250 str( tcpIP ) + ":" + str( tcpPort ) + " " + key
251 response = self.execute( cmd=command, prompt="(.*)", timeout=240 )
252 if utilities.assert_matches( expect='(.*)', actual=response, onpass="show command executed", onfail="show command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700253 main.last_result = main.TRUE
254 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800255 else:
adminbae64d82013-08-01 10:50:15 -0700256 main.last_result = main.FALSE
257 return main.FALSE
258
kelvin8ec71442015-01-15 16:57:00 -0800259 def desc_set( self, **flowParameters ):
260 """
261 desc_set Sets the switch description ( as returned in ofp_desc_stats ) to string ( max length is DESC_STR_LEN )
262 """
263 args = utilities.parse_args( [
264 "TCPIP",
265 "TCPPORT",
266 "STRING" ],
267 **flowParameters )
268
269 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
270 tcpPort = args[ "TCPPORT" ] if args[
271 "TCPPORT" ] is not None else "6634"
272 string = " " + args[ "STRING" ] if args[
273 "STRING" ] is not None else " DESC_STR_LEN"
274 command = "dpctl desc tcp:" + \
275 str( tcpIP ) + ":" + str( tcpPort ) + str( string )
276 response = self.execute(
277 cmd=command,
278 prompt="ETH-Tutorial",
279 timeout=240 )
280 if utilities.assert_matches( expect='@', actual=response, onpass="desc command executed", onfail="desc command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700281 main.last_result = main.TRUE
282 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800283 else:
adminbae64d82013-08-01 10:50:15 -0700284 main.last_result = main.FALSE
285 return main.FALSE
286
kelvin8ec71442015-01-15 16:57:00 -0800287 def dumpDesc( self, **flowParameters ):
288 """
289 dumpDesc Sets the switch description ( as returned in ofp_desc_stats ) to string ( max length is DESC_STR_LEN )
290 """
291 args = utilities.parse_args( [
292 "TCPIP",
293 "TCPPORT",
294 "STRING" ],
295 **flowParameters )
296
297 tcpIP = args[ "TCPIP" ] if args[ "TCPIP" ] is not None else "127.0.0.1"
298 tcpPort = args[ "TCPPORT" ] if args[
299 "TCPPORT" ] is not None else "6634"
300 command = "dpctl dump-desc tcp:" + str( tcpIP ) + ":" + str( tcpPort )
301 response = self.execute(
302 cmd=command,
303 prompt="Serial Num:",
304 timeout=240 )
305 if utilities.assert_matches( expect='stats_reply', actual=response, onpass="desc command executed", onfail="desc command execution Failed" ):
adminbae64d82013-08-01 10:50:15 -0700306 main.last_result = main.TRUE
307 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800308 else:
adminbae64d82013-08-01 10:50:15 -0700309 main.last_result = main.FALSE
310 return main.FALSE
311
312if __name__ != "__main__":
313 import sys
kelvin8ec71442015-01-15 16:57:00 -0800314 sys.modules[ __name__ ] = DpctlCliDriver()
315