blob: f0cfecc703bc31d182955f11a741fd9902a6476a [file] [log] [blame]
timlindbergef8d55d2013-09-27 12:50:13 -07001#!/usr/bin/env python
2
3import time
4import pexpect
kelvin-onlabbbe46482015-01-16 10:44:28 -08005import struct
6import fcntl
7import os
8import sys
9import signal
timlindbergef8d55d2013-09-27 12:50:13 -070010import sys
11import re
12import json
kelvin-onlabbbe46482015-01-16 10:44:28 -080013sys.path.append( "../" )
timlindbergef8d55d2013-09-27 12:50:13 -070014from drivers.common.clidriver import CLI
15
timlindbergef8d55d2013-09-27 12:50:13 -070016
kelvin-onlabbbe46482015-01-16 10:44:28 -080017class QuaggaCliDriver( CLI ):
18
19 def __init__( self ):
20 super( CLI, self ).__init__()
timlindbergef8d55d2013-09-27 12:50:13 -070021
pingping-linc6b86fa2014-12-01 16:18:10 -080022 # TODO: simplify this method
kelvin-onlabbbe46482015-01-16 10:44:28 -080023 def connect( self, **connectargs ):
timlindbergef8d55d2013-09-27 12:50:13 -070024 for key in connectargs:
kelvin-onlabbbe46482015-01-16 10:44:28 -080025 vars( self )[ key ] = connectargs[ key ]
pingping-linc6b86fa2014-12-01 16:18:10 -080026
kelvin-onlabbbe46482015-01-16 10:44:28 -080027 self.name = self.options[ 'name' ]
28 # self.handle = super( QuaggaCliDriver,self ).connect(
kelvin-onlabd3b64892015-01-20 13:26:24 -080029 # userName=self.userName, ipAddress=self.ipAddress,port=self.port,
kelvin-onlabbbe46482015-01-16 10:44:28 -080030 # pwd=self.pwd )
31 self.handle = super(
32 QuaggaCliDriver,
33 self ).connect(
kelvin-onlabd3b64892015-01-20 13:26:24 -080034 userName=self.userName,
35 ipAddress="1.1.1.1",
36 port=self.port,
37 pwd=self.pwd )
kelvin-onlabbbe46482015-01-16 10:44:28 -080038 main.log.info(
39 "connect parameters:" + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -080040 self.userName ) + ";" + str(
41 self.ipAddress ) + ";" + str(
42 self.port ) + ";" + str(
43 self.pwd ) )
timlindbergef8d55d2013-09-27 12:50:13 -070044
pingping-linc6b86fa2014-12-01 16:18:10 -080045 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080046 # self.handle.expect( "",timeout=10 )
47 # self.handle.expect( "\$",timeout=10 )
48 self.handle.sendline( "telnet localhost 2605" )
49 # self.handle.expect( "Password:", timeout=5 )
50 self.handle.expect( "Password:" )
51 self.handle.sendline( "hello" )
52 # self.handle.expect( "bgpd", timeout=5 )
53 self.handle.expect( "bgpd" )
54 self.handle.sendline( "enable" )
55 # self.handle.expect( "bgpd#", timeout=5 )
56 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -070057 return self.handle
kelvin-onlabbbe46482015-01-16 10:44:28 -080058 else:
59 main.log.info( "NO HANDLE" )
timlindbergef8d55d2013-09-27 12:50:13 -070060 return main.FALSE
61
kelvin-onlabd3b64892015-01-20 13:26:24 -080062 def loginQuagga( self, ipAddress ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080063 self.name = self.options[ 'name' ]
64 self.handle = super( QuaggaCliDriver, self ).connect(
kelvin-onlabd3b64892015-01-20 13:26:24 -080065 userName=self.userName, ipAddress=ipAddress,
kelvin-onlabbbe46482015-01-16 10:44:28 -080066 port=self.port, pwd=self.pwd )
kelvin-onlabd3b64892015-01-20 13:26:24 -080067 main.log.info( "connect parameters:" +
68 str( self.userName ) +
69 ";" +
70 str( self.ipAddress ) +
71 ";" +
72 str( self.port ) +
73 ";" +
74 str( self.pwd ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080075
76 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080077 # self.handle.expect( "" )
78 # self.handle.expect( "\$" )
79 self.handle.sendline( "telnet localhost 2605" )
80 # self.handle.expect( "Password:", timeout=5 )
81 self.handle.expect( "Password:" )
82 self.handle.sendline( "hello" )
83 # self.handle.expect( "bgpd", timeout=5 )
84 self.handle.expect( "bgpd" )
85 self.handle.sendline( "enable" )
86 # self.handle.expect( "bgpd#", timeout=5 )
87 self.handle.expect( "bgpd#" )
kelvin-onlabd3b64892015-01-20 13:26:24 -080088 main.log.info( "I in quagga on host " + str( ipAddress ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080089
90 return self.handle
91 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -080092 main.log.info( "NO HANDLE" )
pingping-lin8b306ac2014-11-17 18:13:51 -080093 return main.FALSE
94
kelvin-onlabd3b64892015-01-20 13:26:24 -080095 def enterConfig( self, asn ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080096 main.log.info( "I am in enter_config method!" )
timlindbergef8d55d2013-09-27 12:50:13 -070097 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -080098 self.handle.sendline( "" )
99 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700100 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800101 main.log.warn( "Probably not currently in enable mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700102 self.disconnect()
103 return main.FALSE
kelvin-onlabbbe46482015-01-16 10:44:28 -0800104 self.handle.sendline( "configure terminal" )
105 self.handle.expect( "config", timeout=5 )
106 routerAS = "router bgp " + str( asn )
timlindbergef8d55d2013-09-27 12:50:13 -0700107 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800108 self.handle.sendline( routerAS )
109 self.handle.expect( "config-router", timeout=5 )
timlindbergef8d55d2013-09-27 12:50:13 -0700110 return main.TRUE
111 except:
112 return main.FALSE
pingping-lin8b306ac2014-11-17 18:13:51 -0800113
kelvin-onlabd3b64892015-01-20 13:26:24 -0800114 def generatePrefixes( self, net, numRoutes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800115 main.log.info( "I am in generate_prefixes method!" )
pingping-lin6f6332e2014-11-19 19:13:58 -0800116
kelvin-onlabd3b64892015-01-20 13:26:24 -0800117 # each IP prefix will be composed by
118 #"net" + "." + m + "." + n + "." + x
pingping-lin8b306ac2014-11-17 18:13:51 -0800119 # the length of each IP prefix is 24
120 routes = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800121 routesGen = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800122 m = numRoutes / 256
123 n = numRoutes % 256
124
kelvin-onlabbbe46482015-01-16 10:44:28 -0800125 for i in range( 0, m ):
126 for j in range( 0, 256 ):
127 network = str(
128 net ) + "." + str(
129 i ) + "." + str(
130 j ) + ".0/24"
131 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800132 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800133
kelvin-onlabbbe46482015-01-16 10:44:28 -0800134 for j in range( 0, n ):
135 network = str( net ) + "." + str( m ) + "." + str( j ) + ".0/24"
136 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800137 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800138
kelvin-onlabd3b64892015-01-20 13:26:24 -0800139 if routesGen == numRoutes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800140 main.log.info( "Successfully generated " + str( numRoutes )
141 + " prefixes!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800142 return routes
143 return main.FALSE
pingping-lin6f6332e2014-11-19 19:13:58 -0800144
kelvin-onlabbbe46482015-01-16 10:44:28 -0800145 # This method generates a multiple to single point intent(
146 # MultiPointToSinglePointIntent ) for a given route
kelvin-onlabd3b64892015-01-20 13:26:24 -0800147 def generateExpectedSingleRouteIntent(
148 self,
149 prefix,
150 nextHop,
151 nextHopMac,
152 sdnipData ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800153
154 ingress = []
155 egress = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800156 for peer in sdnipData[ 'bgpPeers' ]:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800157 if peer[ 'ipAddress' ] == nextHop:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800158 egress = "of:" + \
159 str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" +\
160 str( peer[ 'attachmentPort' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800161 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800162 ingress.append( "of:" +
163 str( peer[ 'attachmentDpid' ] ).replace( ":",
164 "" ) + ":" +
165 str( peer[ 'attachmentPort' ] ) )
pingping-lin6f6332e2014-11-19 19:13:58 -0800166
pingping-linc6b86fa2014-12-01 16:18:10 -0800167 selector = "ETH_TYPE{ethType=800},IPV4_DST{ip=" + prefix + "}"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800168 treatment = "[ETH_DST{mac=" + str( nextHopMac ) + "}]"
pingping-lin6f6332e2014-11-19 19:13:58 -0800169
kelvin-onlabbbe46482015-01-16 10:44:28 -0800170 intent = egress + "/" + \
171 str( sorted( ingress ) ) + "/" + selector + "/" + treatment
pingping-lin6f6332e2014-11-19 19:13:58 -0800172 return intent
173
kelvin-onlabd3b64892015-01-20 13:26:24 -0800174 def generateExpectedOnePeerRouteIntents(
175 self,
176 prefixes,
177 nextHop,
178 nextHopMac,
179 sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800180 intents = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800181 sdnipJsonFile = open( sdnipJsonFilePath ).read()
pingping-lin6f6332e2014-11-19 19:13:58 -0800182
kelvin-onlabd3b64892015-01-20 13:26:24 -0800183 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800184
185 for prefix in prefixes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800186 intents.append(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800187 self.generateExpectedSingleRouteIntent(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800188 prefix,
189 nextHop,
190 nextHopMac,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800191 sdnipData ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800192 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800193
194 # TODO
195 # This method generates all expected route intents for all BGP peers
kelvin-onlabd3b64892015-01-20 13:26:24 -0800196 def generateExpectedRouteIntents( self ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800197 intents = []
198 return intents
199
200 # This method extracts all actual routes from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 def extractActualRoutes( self, getRoutesResult ):
202 routesJsonObj = json.loads( getRoutesResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800203
kelvin-onlabd3b64892015-01-20 13:26:24 -0800204 allRoutesActual = []
205 for route in routesJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800206 if route[ 'prefix' ] == '172.16.10.0/24':
pingping-lin6f6332e2014-11-19 19:13:58 -0800207 continue
kelvin-onlabd3b64892015-01-20 13:26:24 -0800208 allRoutesActual.append(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800209 route[ 'prefix' ] + "/" + route[ 'nextHop' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800210
kelvin-onlabd3b64892015-01-20 13:26:24 -0800211 return sorted( allRoutesActual )
pingping-lin6f6332e2014-11-19 19:13:58 -0800212
213 # This method extracts all actual route intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800214 def extractActualRouteIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800215 intents = []
216 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
218 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800219
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800221 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800222 continue
kelvin-onlabd3b64892015-01-20 13:26:24 -0800223 if intent[ 'type' ] == "MultiPointToSinglePointIntent" and intent[
224 'state' ] == 'INSTALLED':
kelvin-onlabbbe46482015-01-16 10:44:28 -0800225 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + str(
226 intent[ 'egress' ][ 'port' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800227 ingress = []
kelvin-onlabbbe46482015-01-16 10:44:28 -0800228 for attachmentPoint in intent[ 'ingress' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 ingress.append( str( attachmentPoint[ 'device' ] ) +
230 ":" + str( attachmentPoint[ 'port' ] ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800231
kelvin-onlabbbe46482015-01-16 10:44:28 -0800232 selector = intent[ 'selector' ].replace(
233 "[", "" ).replace( "]", "" ).replace( " ", "" )
234 if str( selector ).startswith( "IPV4" ):
235 str1, str2 = str( selector ).split( "," )
pingping-linc6b86fa2014-12-01 16:18:10 -0800236 selector = str2 + "," + str1
237
kelvin-onlabbbe46482015-01-16 10:44:28 -0800238 intent = egress + "/" + \
239 str( sorted( ingress ) ) + "/" + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 selector + "/" + intent[ 'treatment' ]
kelvin-onlabbbe46482015-01-16 10:44:28 -0800241 intents.append( intent )
242 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800243
244 # This method extracts all actual BGP intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 def extractActualBgpIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800246 intents = []
247 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
249 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800250
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800252 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800253 continue
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 if intent[ 'type' ] == "PointToPointIntent" and "protocol=6"\
255 in str( intent[ 'selector' ] ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800256 ingress = str( intent[ 'ingress' ][ 'device' ] ) + ":" + str(
257 intent[ 'ingress' ][ 'port' ] )
258 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + str(
259 intent[ 'egress' ][ 'port' ] )
260 selector = str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 intent[ 'selector' ] ).replace(
262 " ",
263 "" ).replace(
264 "[",
265 "" ).replace(
266 "]",
267 "" ).split( "," )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800268 intent = ingress + "/" + egress + \
269 "/" + str( sorted( selector ) )
270 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800271
kelvin-onlabbbe46482015-01-16 10:44:28 -0800272 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800273
kelvin-onlabbbe46482015-01-16 10:44:28 -0800274 # This method generates a single point to single point intent(
275 # PointToPointIntent ) for BGP path
kelvin-onlabd3b64892015-01-20 13:26:24 -0800276 def generateExpectedBgpIntents( self, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800277 from operator import eq
278
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 sdnipJsonFile = open( sdnipJsonFilePath ).read()
280 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800281
282 intents = []
pingping-linc6b86fa2014-12-01 16:18:10 -0800283 bgpPeerAttachmentPoint = ""
kelvin-onlabbbe46482015-01-16 10:44:28 -0800284 bgpSpeakerAttachmentPoint = "of:" + str(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ).replace( ":",
286 "" ) + ":" +\
287 str( sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] )
288 for peer in sdnipData[ 'bgpPeers' ]:
289 bgpPeerAttachmentPoint = "of:" + \
290 str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) +\
291 ":" + str( peer[ 'attachmentPort' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800292 # find out the BGP speaker IP address for this BGP peer
pingping-linc6b86fa2014-12-01 16:18:10 -0800293 bgpSpeakerIpAddress = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 for interfaceAddress in sdnipData[
295 'bgpSpeakers' ][ 0 ][ 'interfaceAddresses' ]:
296 # if eq( interfaceAddress[ 'interfaceDpid' ],sdnipData[
kelvin-onlabbbe46482015-01-16 10:44:28 -0800297 # 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ) and eq(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800298 # interfaceAddress[ 'interfacePort' ], sdnipData[
kelvin-onlabbbe46482015-01-16 10:44:28 -0800299 # 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] ):
kelvin-onlabd3b64892015-01-20 13:26:24 -0800300 if eq(
301 interfaceAddress[ 'interfaceDpid' ],
302 peer[ 'attachmentDpid' ] ) and eq(
303 interfaceAddress[ 'interfacePort' ],
304 peer[ 'attachmentPort' ] ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800305 bgpSpeakerIpAddress = interfaceAddress[ 'ipAddress' ]
pingping-lin6f6332e2014-11-19 19:13:58 -0800306 break
307 else:
308 continue
309
kelvin-onlabbbe46482015-01-16 10:44:28 -0800310 # from bgpSpeakerAttachmentPoint to bgpPeerAttachmentPoint
311 # direction
kelvin-onlabd3b64892015-01-20 13:26:24 -0800312 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress +\
313 "/32}," + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," +\
314 "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800},\
315 TCP_DST{tcpPort=179}"
316 selector = selectorStr.replace( " ", "" ).replace(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800317 "[", "" ).replace( "]", "" ).split( "," )
318 intent = bgpSpeakerAttachmentPoint + "/" + \
319 bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
320 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800321
kelvin-onlabd3b64892015-01-20 13:26:24 -0800322 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," +\
323 "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," +\
324 "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800},\
325 TCP_SRC{tcpPort=179}"
326 selector = selectorStr.replace( " ", "" ).replace(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800327 "[", "" ).replace( "]", "" ).split( "," )
328 intent = bgpSpeakerAttachmentPoint + "/" + \
329 bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
330 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800331
kelvin-onlabbbe46482015-01-16 10:44:28 -0800332 # from bgpPeerAttachmentPoint to bgpSpeakerAttachmentPoint
333 # direction
kelvin-onlabd3b64892015-01-20 13:26:24 -0800334 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," +\
335 "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," + \
336 "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800},\
337 TCP_DST{tcpPort=179}"
338 selector = selectorStr.replace( " ", "" ).replace(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800339 "[", "" ).replace( "]", "" ).split( "," )
340 intent = bgpPeerAttachmentPoint + "/" + \
341 bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
342 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800343
kelvin-onlabd3b64892015-01-20 13:26:24 -0800344 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," +\
345 "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," +\
346 "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800},\
347 TCP_SRC{tcpPort=179}"
348 selector = selectorStr.replace( " ", "" ).replace(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800349 "[", "" ).replace( "]", "" ).split( "," )
350 intent = bgpPeerAttachmentPoint + "/" + \
351 bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
352 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800353
kelvin-onlabbbe46482015-01-16 10:44:28 -0800354 return sorted( intents )
pingping-linc6b86fa2014-12-01 16:18:10 -0800355
kelvin-onlabd3b64892015-01-20 13:26:24 -0800356 def addRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800357 main.log.info( "I am in add_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800358
kelvin-onlabd3b64892015-01-20 13:26:24 -0800359 routesAdded = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800360 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800361 self.handle.sendline( "" )
362 # self.handle.expect( "config-router" )
363 self.handle.expect( "config-router", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800364 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800365 main.log.warn( "Probably not in config-router mode!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800366 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800367 main.log.info( "Start to add routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800368
kelvin-onlabbbe46482015-01-16 10:44:28 -0800369 for i in range( 0, len( routes ) ):
370 routeCmd = "network " + routes[ i ]
pingping-lin8b306ac2014-11-17 18:13:51 -0800371 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800372 self.handle.sendline( routeCmd )
373 self.handle.expect( "bgpd", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800374 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800375 main.log.warn( "Failed to add route" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800376 self.disconnect()
377 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800378 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800379 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800380 main.log.info( "Finished adding routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800381 return main.TRUE
382 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800383
kelvin-onlabd3b64892015-01-20 13:26:24 -0800384 def deleteRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800385 main.log.info( "I am in delete_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800386
kelvin-onlabd3b64892015-01-20 13:26:24 -0800387 routesAdded = 0
pingping-linc6b86fa2014-12-01 16:18:10 -0800388 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800389 self.handle.sendline( "" )
390 # self.handle.expect( "config-router" )
391 self.handle.expect( "config-router", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800392 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800393 main.log.warn( "Probably not in config-router mode!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800394 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800395 main.log.info( "Start to delete routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800396
kelvin-onlabbbe46482015-01-16 10:44:28 -0800397 for i in range( 0, len( routes ) ):
398 routeCmd = "no network " + routes[ i ]
pingping-linc6b86fa2014-12-01 16:18:10 -0800399 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800400 self.handle.sendline( routeCmd )
401 self.handle.expect( "bgpd", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800402 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800403 main.log.warn( "Failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800404 self.disconnect()
405 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800406 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800407 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800408 main.log.info( "Finished deleting routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800409 return main.TRUE
410 return main.FALSE
411
kelvin-onlabd3b64892015-01-20 13:26:24 -0800412 def pingTest( self, ipAddress, pingTestFile, pingTestResultFile ):
413 main.log.info( "Start the ping test on host:" + str( ipAddress ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800414
kelvin-onlabbbe46482015-01-16 10:44:28 -0800415 self.name = self.options[ 'name' ]
416 self.handle = super( QuaggaCliDriver, self ).connect(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800417 userName=self.userName, ipAddress=ipAddress,
kelvin-onlabbbe46482015-01-16 10:44:28 -0800418 port=self.port, pwd=self.pwd )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800419 main.log.info( "connect parameters:" +
420 str( self.userName ) +
421 ";" +
422 str( self.ipAddress ) +
423 ";" +
424 str( self.port ) +
425 ";" +
426 str( self.pwd ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800427
428 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800429 # self.handle.expect( "" )
430 # self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800431 main.log.info( "I in host " + str( ipAddress ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800432 main.log.info(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 pingTestFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800434 " > " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800435 pingTestResultFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800436 " &" )
437 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800438 pingTestFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800439 " > " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800440 pingTestResultFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800441 " &" )
442 self.handle.expect( "\$", timeout=60 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800443 handle = self.handle.before
444
445 return handle
446 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800447 main.log.info( "NO HANDLE" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800448 return main.FALSE
449
kelvin-onlabd3b64892015-01-20 13:26:24 -0800450 # Please use the generateRoutes plus addRoutes instead of this one
451 def addRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700452 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800453 self.handle.sendline( "" )
454 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700455 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800456 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700457 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800458 main.log.info( "Adding Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800459 j = 0
460 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700461 while numRoutes > 255:
462 numRoutes = numRoutes - 255
463 j = j + 1
464 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800465 routesAdded = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700466 if numRoutes > 255:
467 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800468 for m in range( 1, j + 1 ):
469 for n in range( 1, numRoutes + 1 ):
kelvin-onlabd3b64892015-01-20 13:26:24 -0800470 network = str( net ) + "." + str( m ) + \
471 "." + str( n ) + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700472 routeCmd = "network " + network
473 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800474 self.handle.sendline( routeCmd )
475 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700476 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800477 main.log.warn( "failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800478 self.disconnect()
479 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800480 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 routesAdded = routesAdded + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800482 for d in range( j + 1, j + 2 ):
483 for e in range( 1, k + 1 ):
484 network = str(
485 net ) + "." + str(
486 d ) + "." + str(
487 e ) + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700488 routeCmd = "network " + network
489 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800490 self.handle.sendline( routeCmd )
491 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700492 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800493 main.log.warn( "failed to add route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700494 self.disconnect
pingping-linc6b86fa2014-12-01 16:18:10 -0800495 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800496 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800497 routesAdded = routesAdded + 1
498 if routesAdded == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700499 return main.TRUE
500 return main.FALSE
pingping-lin6f6332e2014-11-19 19:13:58 -0800501
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 def delRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700503 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800504 self.handle.sendline( "" )
505 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700506 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800507 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700508 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800509 main.log.info( "Deleting Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800510 j = 0
511 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700512 while numRoutes > 255:
513 numRoutes = numRoutes - 255
514 j = j + 1
515 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800516 routesDeleted = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700517 if numRoutes > 255:
518 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800519 for m in range( 1, j + 1 ):
520 for n in range( 1, numRoutes + 1 ):
kelvin-onlabd3b64892015-01-20 13:26:24 -0800521 network = str( net ) + "." + str( m ) + \
522 "." + str( n ) + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700523 routeCmd = "no network " + network
524 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800525 self.handle.sendline( routeCmd )
526 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700527 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800528 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700529 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800530 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800531 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800532 routesDeleted = routesDeleted + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800533 for d in range( j + 1, j + 2 ):
534 for e in range( 1, k + 1 ):
kelvin-onlabd3b64892015-01-20 13:26:24 -0800535 network = str( net ) + "." + str( d ) + \
536 "." + str( e ) + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700537 routeCmd = "no network " + network
538 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800539 self.handle.sendline( routeCmd )
540 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700541 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800542 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700543 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800544 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800545 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800546 routesDeleted = routesDeleted + 1
547 if routesDeleted == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700548 return main.TRUE
549 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 def checkRoutes( self, brand, ip, user, pw ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800552 def pronto( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700553 print "Connecting to Pronto switch"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800554 child = pexpect.spawn( "telnet " + ip )
555 i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700556 if i == 0:
557 print "Username and password required. Passing login info."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800558 child.sendline( user )
559 child.expect( "Password:" )
560 child.sendline( passwd )
561 child.expect( "CLI#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700562 print "Logged in, getting flowtable."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800563 child.sendline( "flowtable brief" )
564 for t in range( 9 ):
timlindbergef8d55d2013-09-27 12:50:13 -0700565 t2 = 9 - t
kelvin-onlabbbe46482015-01-16 10:44:28 -0800566 print "\r" + str( t2 )
567 sys.stdout.write( "\033[F" )
568 time.sleep( 1 )
timlindbergef8d55d2013-09-27 12:50:13 -0700569 print "Scanning flowtable"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800570 child.expect( "Flow table show" )
timlindbergef8d55d2013-09-27 12:50:13 -0700571 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800572 while True:
573 i = child.expect(
574 [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 'CLI#',
576 pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700577 if i == 0:
578 count = count + 1
579 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800580 print "Pronto flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700581 break
582 else:
583 break
kelvin-onlabbbe46482015-01-16 10:44:28 -0800584
585 def cisco( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700586 print "Establishing Cisco switch connection"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800587 child = pexpect.spawn( "ssh " + user + "@" + ip )
588 i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700589 if i == 0:
590 print "Password required. Passing now."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800591 child.sendline( passwd )
592 child.expect( "#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700593 print "Logged in. Retrieving flow table then counting flows."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800594 child.sendline( "show openflow switch all flows all" )
595 child.expect( "Logical Openflow Switch" )
timlindbergef8d55d2013-09-27 12:50:13 -0700596 print "Flow table retrieved. Counting flows"
597 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800598 while True:
599 i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700600 if i == 0:
601 count = count + 1
602 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800603 print "Cisco flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700604 break
605 else:
606 break
607 if brand == "pronto" or brand == "PRONTO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800608 pronto( ip, user, passwd )
pingping-linc6b86fa2014-12-01 16:18:10 -0800609 # elif brand == "cisco" or brand == "CISCO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800610 # cisco( ip,user,passwd )
611
612 def disconnect( self ):
613 """
614 Called when Test is complete to disconnect the Quagga handle.
615 """
timlindbergef8d55d2013-09-27 12:50:13 -0700616 response = ''
617 try:
618 self.handle.close()
619 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800620 main.log.error( "Connection failed to the host" )
timlindbergef8d55d2013-09-27 12:50:13 -0700621 response = main.FALSE
622 return response