blob: 8bd4754c3763070f5fcec53cef9047d6d5c7ba8e [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(
pingping-linc1c696e2015-01-27 13:46:44 -080029 # user_name=self.user_name, ip_address=self.ip_address,port=self.port,
kelvin-onlabbbe46482015-01-16 10:44:28 -080030 # pwd=self.pwd )
pingping-lin4e7b0d32015-01-27 18:06:22 -080031 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080032 user_name=self.user_name,
33 ip_address="1.1.1.1",
34 port=self.port,
35 pwd=self.pwd )
pingping-lina600d9b2015-01-30 13:57:26 -080036 #main.log.info( "connect parameters:" + str( self.user_name ) + ";"
37 # + str( self.ip_address ) + ";" + str( self.port )
38 # + ";" + str(self.pwd ) )
timlindbergef8d55d2013-09-27 12:50:13 -070039
pingping-linc6b86fa2014-12-01 16:18:10 -080040 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080041 # self.handle.expect( "",timeout=10 )
42 # self.handle.expect( "\$",timeout=10 )
43 self.handle.sendline( "telnet localhost 2605" )
44 # self.handle.expect( "Password:", timeout=5 )
45 self.handle.expect( "Password:" )
46 self.handle.sendline( "hello" )
47 # self.handle.expect( "bgpd", timeout=5 )
48 self.handle.expect( "bgpd" )
49 self.handle.sendline( "enable" )
50 # self.handle.expect( "bgpd#", timeout=5 )
51 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -070052 return self.handle
kelvin-onlabbbe46482015-01-16 10:44:28 -080053 else:
54 main.log.info( "NO HANDLE" )
timlindbergef8d55d2013-09-27 12:50:13 -070055 return main.FALSE
56
pingping-linc1c696e2015-01-27 13:46:44 -080057 def loginQuagga( self, ip_address ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080058 self.name = self.options[ 'name' ]
59 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080060 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -080061 port=self.port, pwd=self.pwd )
pingping-linc1c696e2015-01-27 13:46:44 -080062 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
pingping-lin4e7b0d32015-01-27 18:06:22 -080063 + str( self.ip_address ) + ";" + str( self.port )
64 + ";" + str( self.pwd ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080065
66 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080067 # self.handle.expect( "" )
68 # self.handle.expect( "\$" )
69 self.handle.sendline( "telnet localhost 2605" )
70 # self.handle.expect( "Password:", timeout=5 )
71 self.handle.expect( "Password:" )
72 self.handle.sendline( "hello" )
73 # self.handle.expect( "bgpd", timeout=5 )
74 self.handle.expect( "bgpd" )
75 self.handle.sendline( "enable" )
76 # self.handle.expect( "bgpd#", timeout=5 )
77 self.handle.expect( "bgpd#" )
pingping-linc1c696e2015-01-27 13:46:44 -080078 main.log.info( "I am in quagga on host " + str( ip_address ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080079
80 return self.handle
81 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -080082 main.log.info( "NO HANDLE" )
pingping-lin8b306ac2014-11-17 18:13:51 -080083 return main.FALSE
84
kelvin-onlabd3b64892015-01-20 13:26:24 -080085 def enterConfig( self, asn ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080086 main.log.info( "I am in enter_config method!" )
timlindbergef8d55d2013-09-27 12:50:13 -070087 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -080088 self.handle.sendline( "" )
89 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -070090 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -080091 main.log.warn( "Probably not currently in enable mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -070092 self.disconnect()
93 return main.FALSE
kelvin-onlabbbe46482015-01-16 10:44:28 -080094 self.handle.sendline( "configure terminal" )
95 self.handle.expect( "config", timeout=5 )
96 routerAS = "router bgp " + str( asn )
timlindbergef8d55d2013-09-27 12:50:13 -070097 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -080098 self.handle.sendline( routerAS )
99 self.handle.expect( "config-router", timeout=5 )
timlindbergef8d55d2013-09-27 12:50:13 -0700100 return main.TRUE
101 except:
102 return main.FALSE
pingping-lin8b306ac2014-11-17 18:13:51 -0800103
kelvin-onlabd3b64892015-01-20 13:26:24 -0800104 def generatePrefixes( self, net, numRoutes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800105 main.log.info( "I am in generate_prefixes method!" )
pingping-lin6f6332e2014-11-19 19:13:58 -0800106
pingping-lin4e7b0d32015-01-27 18:06:22 -0800107 # each IP prefix is composed by "net" + "." + m + "." + n + "." + x
pingping-lin8b306ac2014-11-17 18:13:51 -0800108 # the length of each IP prefix is 24
109 routes = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800110 routesGen = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800111 m = numRoutes / 256
112 n = numRoutes % 256
113
kelvin-onlabbbe46482015-01-16 10:44:28 -0800114 for i in range( 0, m ):
115 for j in range( 0, 256 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800116 network = str( net ) + "." + str( i ) + "." + str( j ) \
117 + ".0/24"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800118 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800119 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800120
kelvin-onlabbbe46482015-01-16 10:44:28 -0800121 for j in range( 0, n ):
122 network = str( net ) + "." + str( m ) + "." + str( j ) + ".0/24"
123 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800124 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800125
kelvin-onlabd3b64892015-01-20 13:26:24 -0800126 if routesGen == numRoutes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800127 main.log.info( "Successfully generated " + str( numRoutes )
128 + " prefixes!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800129 return routes
130 return main.FALSE
pingping-lin6f6332e2014-11-19 19:13:58 -0800131
kelvin-onlabbbe46482015-01-16 10:44:28 -0800132 # This method generates a multiple to single point intent(
133 # MultiPointToSinglePointIntent ) for a given route
pingping-lin4e7b0d32015-01-27 18:06:22 -0800134 def generateExpectedSingleRouteIntent( self, prefix, nextHop, nextHopMac,
135 sdnipData ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800136
pingping-linc1c696e2015-01-27 13:46:44 -0800137 ingresses = []
pingping-lin6f6332e2014-11-19 19:13:58 -0800138 egress = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800139 for peer in sdnipData[ 'bgpPeers' ]:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800140 if peer[ 'ipAddress' ] == nextHop:
pingping-linc1c696e2015-01-27 13:46:44 -0800141 egress = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800142 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
143 + str( peer[ 'attachmentPort' ] )
pingping-linc1c696e2015-01-27 13:46:44 -0800144 for peer in sdnipData[ 'bgpPeers' ]:
145 if not peer[ 'ipAddress' ] == nextHop:
146 ingress = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800147 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
148 + str( peer[ 'attachmentPort' ] )
pingping-linc1c696e2015-01-27 13:46:44 -0800149 if not ingress == egress and ingress not in ingresses:
150 ingresses.append( ingress )
151 # ingresses.append( "of:" + str( peer[ 'attachmentDpid' ]
152 # ).replace( ":", "" ) + ":" + str( peer[ 'attachmentPort'
153 # ] ) )
pingping-lin6f6332e2014-11-19 19:13:58 -0800154
pingping-linc6b86fa2014-12-01 16:18:10 -0800155 selector = "ETH_TYPE{ethType=800},IPV4_DST{ip=" + prefix + "}"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800156 treatment = "[ETH_DST{mac=" + str( nextHopMac ) + "}]"
pingping-lin6f6332e2014-11-19 19:13:58 -0800157
pingping-lin4e7b0d32015-01-27 18:06:22 -0800158 intent = egress + "/" + str( sorted( ingresses ) ) + "/" + \
159 selector + "/" + treatment
pingping-lin6f6332e2014-11-19 19:13:58 -0800160 return intent
161
pingping-lin4e7b0d32015-01-27 18:06:22 -0800162 def generateExpectedOnePeerRouteIntents( self, prefixes, nextHop,
163 nextHopMac, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800164 intents = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800165 sdnipJsonFile = open( sdnipJsonFilePath ).read()
pingping-lin6f6332e2014-11-19 19:13:58 -0800166
kelvin-onlabd3b64892015-01-20 13:26:24 -0800167 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800168
169 for prefix in prefixes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800170 intents.append(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800171 self.generateExpectedSingleRouteIntent(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800172 prefix, nextHop, nextHopMac, sdnipData ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800173 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800174
175 # TODO
176 # This method generates all expected route intents for all BGP peers
kelvin-onlabd3b64892015-01-20 13:26:24 -0800177 def generateExpectedRouteIntents( self ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800178 intents = []
179 return intents
180
181 # This method extracts all actual routes from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 def extractActualRoutes( self, getRoutesResult ):
183 routesJsonObj = json.loads( getRoutesResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800184
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 allRoutesActual = []
186 for route in routesJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800187 if route[ 'prefix' ] == '172.16.10.0/24':
pingping-lin6f6332e2014-11-19 19:13:58 -0800188 continue
kelvin-onlabd3b64892015-01-20 13:26:24 -0800189 allRoutesActual.append(
kelvin-onlabbbe46482015-01-16 10:44:28 -0800190 route[ 'prefix' ] + "/" + route[ 'nextHop' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800191
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 return sorted( allRoutesActual )
pingping-lina600d9b2015-01-30 13:57:26 -0800193 def extractActualRoutesNew( self, getRoutesResult ):
194 routesJsonObj = json.loads( getRoutesResult )
195
196 allRoutesActual = []
197 for route in routesJsonObj['routes4']:
198 if route[ 'prefix' ] == '172.16.10.0/24':
199 continue
200 allRoutesActual.append(
201 route[ 'prefix' ] + "/" + route[ 'nextHop' ] )
202
203 return sorted( allRoutesActual )
pingping-lin6f6332e2014-11-19 19:13:58 -0800204
205 # This method extracts all actual route intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800206 def extractActualRouteIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800207 intents = []
208 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800209 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
210 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800211
kelvin-onlabd3b64892015-01-20 13:26:24 -0800212 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800213 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800214 continue
pingping-lin4e7b0d32015-01-27 18:06:22 -0800215 if intent[ 'type' ] == "MultiPointToSinglePointIntent" \
216 and intent[ 'state' ] == 'INSTALLED':
217 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" \
218 + str( intent[ 'egress' ][ 'port' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800219 ingress = []
kelvin-onlabbbe46482015-01-16 10:44:28 -0800220 for attachmentPoint in intent[ 'ingress' ]:
pingping-linc1c696e2015-01-27 13:46:44 -0800221 ingress.append(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800222 str( attachmentPoint[ 'device' ] ) + ":"
223 + str( attachmentPoint[ 'port' ] ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800224
kelvin-onlabbbe46482015-01-16 10:44:28 -0800225 selector = intent[ 'selector' ].replace(
226 "[", "" ).replace( "]", "" ).replace( " ", "" )
227 if str( selector ).startswith( "IPV4" ):
228 str1, str2 = str( selector ).split( "," )
pingping-linc6b86fa2014-12-01 16:18:10 -0800229 selector = str2 + "," + str1
230
pingping-lin4e7b0d32015-01-27 18:06:22 -0800231 intent = egress + "/" + str( sorted( ingress ) ) + "/" + \
232 selector + "/" + intent[ 'treatment' ]
kelvin-onlabbbe46482015-01-16 10:44:28 -0800233 intents.append( intent )
234 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800235
236 # This method extracts all actual BGP intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 def extractActualBgpIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800238 intents = []
239 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
241 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800242
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800244 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800245 continue
pingping-lin4e7b0d32015-01-27 18:06:22 -0800246 if intent[ 'type' ] == "PointToPointIntent" \
247 and "protocol=6" in str( intent[ 'selector' ] ):
248 ingress = str( intent[ 'ingress' ][ 'device' ] ) + ":" \
249 + str( intent[ 'ingress' ][ 'port' ] )
250 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + \
251 str( intent[ 'egress' ][ 'port' ] )
252 selector = str( intent[ 'selector' ] ).replace( " ", "" )\
253 .replace( "[", "" ).replace( "]", "" ).split( "," )
254 intent = ingress + "/" + egress + "/" + \
255 str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800256 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800257
kelvin-onlabbbe46482015-01-16 10:44:28 -0800258 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800259
kelvin-onlabbbe46482015-01-16 10:44:28 -0800260 # This method generates a single point to single point intent(
261 # PointToPointIntent ) for BGP path
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 def generateExpectedBgpIntents( self, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800263 from operator import eq
264
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 sdnipJsonFile = open( sdnipJsonFilePath ).read()
266 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800267
268 intents = []
pingping-linc6b86fa2014-12-01 16:18:10 -0800269 bgpPeerAttachmentPoint = ""
kelvin-onlabbbe46482015-01-16 10:44:28 -0800270 bgpSpeakerAttachmentPoint = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800271 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] )\
272 .replace( ":", "" ) + ":" \
273 + str( sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 for peer in sdnipData[ 'bgpPeers' ]:
pingping-lin4e7b0d32015-01-27 18:06:22 -0800275 bgpPeerAttachmentPoint = "of:" \
276 + str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) \
277 + ":" + str( peer[ 'attachmentPort' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800278 # find out the BGP speaker IP address for this BGP peer
pingping-linc6b86fa2014-12-01 16:18:10 -0800279 bgpSpeakerIpAddress = ""
pingping-lin4e7b0d32015-01-27 18:06:22 -0800280 for interfaceAddress in \
281 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'interfaceAddresses' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800282 # if eq( interfaceAddress[ 'interfaceDpid' ],sdnipData[
kelvin-onlabbbe46482015-01-16 10:44:28 -0800283 # 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ) and eq(
pingping-linc1c696e2015-01-27 13:46:44 -0800284 # interfaceAddress[ 'interfacePort' ], sdnipData[ 'bgpSpeakers'
285 # ][ 0 ][ 'attachmentPort' ] ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800286 if eq( interfaceAddress[ 'interfaceDpid' ],
287 peer[ 'attachmentDpid' ] ) \
288 and eq( interfaceAddress[ 'interfacePort' ],
289 peer[ 'attachmentPort' ] ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800290 bgpSpeakerIpAddress = interfaceAddress[ 'ipAddress' ]
pingping-lin6f6332e2014-11-19 19:13:58 -0800291 break
292 else:
293 continue
294
kelvin-onlabbbe46482015-01-16 10:44:28 -0800295 # from bgpSpeakerAttachmentPoint to bgpPeerAttachmentPoint
296 # direction
pingping-lin4e7b0d32015-01-27 18:06:22 -0800297 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
298 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
299 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
300 TCP_DST{tcpPort=179}"
301 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
302 .replace( "]", "" ).split( "," )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800303 intent = bgpSpeakerAttachmentPoint + "/" + \
304 bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
305 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800306
pingping-lin4e7b0d32015-01-27 18:06:22 -0800307 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
308 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
309 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
310 TCP_SRC{tcpPort=179}"
311 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
312 .replace( "]", "" ).split( "," )
313 intent = bgpSpeakerAttachmentPoint + "/" \
314 + bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800315 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800316
kelvin-onlabbbe46482015-01-16 10:44:28 -0800317 # from bgpPeerAttachmentPoint to bgpSpeakerAttachmentPoint
318 # direction
pingping-lin4e7b0d32015-01-27 18:06:22 -0800319 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
320 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
321 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
322 TCP_DST{tcpPort=179}"
323 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
324 .replace( "]", "" ).split( "," )
325 intent = bgpPeerAttachmentPoint + "/" \
326 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800327 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800328
pingping-lin4e7b0d32015-01-27 18:06:22 -0800329 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
330 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
331 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
332 TCP_SRC{tcpPort=179}"
333 selector = selectorStr.replace( " ", "" ).replace( "[", "" )\
334 .replace( "]", "" ).split( "," )
335 intent = bgpPeerAttachmentPoint + "/" \
336 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800337 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800338
kelvin-onlabbbe46482015-01-16 10:44:28 -0800339 return sorted( intents )
pingping-linc6b86fa2014-12-01 16:18:10 -0800340
kelvin-onlabd3b64892015-01-20 13:26:24 -0800341 def addRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800342 main.log.info( "I am in add_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800343
kelvin-onlabd3b64892015-01-20 13:26:24 -0800344 routesAdded = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800345 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800346 self.handle.sendline( "" )
347 # self.handle.expect( "config-router" )
348 self.handle.expect( "config-router", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800349 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800350 main.log.warn( "Probably not in config-router mode!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800351 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800352 main.log.info( "Start to add routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800353
kelvin-onlabbbe46482015-01-16 10:44:28 -0800354 for i in range( 0, len( routes ) ):
355 routeCmd = "network " + routes[ i ]
pingping-lin8b306ac2014-11-17 18:13:51 -0800356 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800357 self.handle.sendline( routeCmd )
358 self.handle.expect( "bgpd", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800359 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800360 main.log.warn( "Failed to add route" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800361 self.disconnect()
pingping-linc1c696e2015-01-27 13:46:44 -0800362 # waitTimer = 1.00 / routeRate
363 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800364 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800365 main.log.info( "Finished adding routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800366 return main.TRUE
367 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800368
kelvin-onlabd3b64892015-01-20 13:26:24 -0800369 def deleteRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800370 main.log.info( "I am in delete_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800371
kelvin-onlabd3b64892015-01-20 13:26:24 -0800372 routesAdded = 0
pingping-linc6b86fa2014-12-01 16:18:10 -0800373 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800374 self.handle.sendline( "" )
375 # self.handle.expect( "config-router" )
376 self.handle.expect( "config-router", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800377 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800378 main.log.warn( "Probably not in config-router mode!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800379 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800380 main.log.info( "Start to delete routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800381
kelvin-onlabbbe46482015-01-16 10:44:28 -0800382 for i in range( 0, len( routes ) ):
383 routeCmd = "no network " + routes[ i ]
pingping-linc6b86fa2014-12-01 16:18:10 -0800384 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800385 self.handle.sendline( routeCmd )
386 self.handle.expect( "bgpd", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800387 except:
pingping-lin4e7b0d32015-01-27 18:06:22 -0800388 main.log.warn( "Failed to delete route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800389 self.disconnect()
pingping-linc1c696e2015-01-27 13:46:44 -0800390 # waitTimer = 1.00 / routeRate
391 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800392 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800393 main.log.info( "Finished deleting routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800394 return main.TRUE
395 return main.FALSE
396
pingping-linc1c696e2015-01-27 13:46:44 -0800397 def pingTest( self, ip_address, pingTestFile, pingTestResultFile ):
398 main.log.info( "Start the ping test on host:" + str( ip_address ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800399
kelvin-onlabbbe46482015-01-16 10:44:28 -0800400 self.name = self.options[ 'name' ]
401 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -0800402 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -0800403 port=self.port, pwd=self.pwd )
pingping-linc1c696e2015-01-27 13:46:44 -0800404 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
pingping-lin4e7b0d32015-01-27 18:06:22 -0800405 + str( self.ip_address ) + ";" + str( self.port )
406 + ";" + str( self.pwd ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800407
408 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800409 # self.handle.expect( "" )
410 # self.handle.expect( "\$" )
pingping-linc1c696e2015-01-27 13:46:44 -0800411 main.log.info( "I in host " + str( ip_address ) )
412 main.log.info( pingTestFile + " > " + pingTestResultFile + " &" )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800413 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800414 pingTestFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800415 " > " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800416 pingTestResultFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800417 " &" )
418 self.handle.expect( "\$", timeout=60 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800419 handle = self.handle.before
420
421 return handle
422 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800423 main.log.info( "NO HANDLE" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800424 return main.FALSE
425
pingping-lin4e7b0d32015-01-27 18:06:22 -0800426 # Please use the generateRoutes plus addRoutes instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800427 def addRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700428 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800429 self.handle.sendline( "" )
430 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700431 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800432 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700433 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800434 main.log.info( "Adding Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800435 j = 0
436 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700437 while numRoutes > 255:
438 numRoutes = numRoutes - 255
439 j = j + 1
440 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800441 routesAdded = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700442 if numRoutes > 255:
443 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800444 for m in range( 1, j + 1 ):
445 for n in range( 1, numRoutes + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800446 network = str( net ) + "." + str( m ) + "." + str( n ) \
447 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700448 routeCmd = "network " + network
449 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800450 self.handle.sendline( routeCmd )
451 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700452 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800453 main.log.warn( "failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800454 self.disconnect()
455 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800456 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800457 routesAdded = routesAdded + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800458 for d in range( j + 1, j + 2 ):
459 for e in range( 1, k + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800460 network = str( net ) + "." + str( d ) + "." + str( e ) \
461 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700462 routeCmd = "network " + network
463 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800464 self.handle.sendline( routeCmd )
465 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700466 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800467 main.log.warn( "failed to add route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700468 self.disconnect
pingping-linc6b86fa2014-12-01 16:18:10 -0800469 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800470 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800471 routesAdded = routesAdded + 1
472 if routesAdded == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700473 return main.TRUE
474 return main.FALSE
pingping-lin0904ad02015-01-30 15:18:14 -0800475
pingping-lin4e7b0d32015-01-27 18:06:22 -0800476 # Please use deleteRoutes method instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800477 def delRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700478 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800479 self.handle.sendline( "" )
480 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700481 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800482 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700483 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800484 main.log.info( "Deleting Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800485 j = 0
486 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700487 while numRoutes > 255:
488 numRoutes = numRoutes - 255
489 j = j + 1
490 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800491 routesDeleted = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700492 if numRoutes > 255:
493 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800494 for m in range( 1, j + 1 ):
495 for n in range( 1, numRoutes + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800496 network = str( net ) + "." + str( m ) + "." + str( n ) \
497 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700498 routeCmd = "no network " + network
499 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800500 self.handle.sendline( routeCmd )
501 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700502 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800503 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700504 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800505 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800506 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800507 routesDeleted = routesDeleted + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800508 for d in range( j + 1, j + 2 ):
509 for e in range( 1, k + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800510 network = str( net ) + "." + str( d ) + "." + str( e ) \
511 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700512 routeCmd = "no network " + network
513 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800514 self.handle.sendline( routeCmd )
515 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700516 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800517 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700518 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800519 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800520 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800521 routesDeleted = routesDeleted + 1
522 if routesDeleted == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700523 return main.TRUE
524 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800525
kelvin-onlabd3b64892015-01-20 13:26:24 -0800526 def checkRoutes( self, brand, ip, user, pw ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800527 def pronto( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700528 print "Connecting to Pronto switch"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800529 child = pexpect.spawn( "telnet " + ip )
530 i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700531 if i == 0:
pingping-linc1c696e2015-01-27 13:46:44 -0800532 print "user_name and password required. Passing login info."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800533 child.sendline( user )
534 child.expect( "Password:" )
535 child.sendline( passwd )
536 child.expect( "CLI#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700537 print "Logged in, getting flowtable."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800538 child.sendline( "flowtable brief" )
539 for t in range( 9 ):
timlindbergef8d55d2013-09-27 12:50:13 -0700540 t2 = 9 - t
kelvin-onlabbbe46482015-01-16 10:44:28 -0800541 print "\r" + str( t2 )
542 sys.stdout.write( "\033[F" )
543 time.sleep( 1 )
timlindbergef8d55d2013-09-27 12:50:13 -0700544 print "Scanning flowtable"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800545 child.expect( "Flow table show" )
timlindbergef8d55d2013-09-27 12:50:13 -0700546 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800547 while True:
pingping-lin0904ad02015-01-30 15:18:14 -0800548 i = child.expect( [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
pingping-lin4e7b0d32015-01-27 18:06:22 -0800549 'CLI#', pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700550 if i == 0:
551 count = count + 1
552 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800553 print "Pronto flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700554 break
555 else:
556 break
kelvin-onlabbbe46482015-01-16 10:44:28 -0800557
558 def cisco( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700559 print "Establishing Cisco switch connection"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800560 child = pexpect.spawn( "ssh " + user + "@" + ip )
561 i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700562 if i == 0:
563 print "Password required. Passing now."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800564 child.sendline( passwd )
565 child.expect( "#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700566 print "Logged in. Retrieving flow table then counting flows."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800567 child.sendline( "show openflow switch all flows all" )
568 child.expect( "Logical Openflow Switch" )
timlindbergef8d55d2013-09-27 12:50:13 -0700569 print "Flow table retrieved. Counting flows"
570 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800571 while True:
572 i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700573 if i == 0:
574 count = count + 1
575 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800576 print "Cisco flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700577 break
578 else:
579 break
580 if brand == "pronto" or brand == "PRONTO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800581 pronto( ip, user, passwd )
pingping-linc6b86fa2014-12-01 16:18:10 -0800582 # elif brand == "cisco" or brand == "CISCO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800583 # cisco( ip,user,passwd )
584
585 def disconnect( self ):
586 """
587 Called when Test is complete to disconnect the Quagga handle.
588 """
timlindbergef8d55d2013-09-27 12:50:13 -0700589 response = ''
590 try:
591 self.handle.close()
592 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800593 main.log.error( "Connection failed to the host" )
timlindbergef8d55d2013-09-27 12:50:13 -0700594 response = main.FALSE
595 return response
pingping-linc1c696e2015-01-27 13:46:44 -0800596