blob: 98f83d2ba538478901b6e81f8e6f4d91a195f0a5 [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-onlab08679eb2015-01-21 16:11:48 -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 )
kelvin-onlab2c4342a2015-01-28 15:59:53 -080031 self.handle = super( QuaggaCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080032 user_name=self.user_name,
kelvin-onlab2c4342a2015-01-28 15:59:53 -080033 ip_address="1.1.1.1",
34 port=self.port,
35 pwd=self.pwd )
36 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
kelvin-onlab08679eb2015-01-21 16:11:48 -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(
kelvin-onlab08679eb2015-01-21 16:11:48 -080060 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -080061 port=self.port, pwd=self.pwd )
kelvin-onlab2c4342a2015-01-28 15:59:53 -080062 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
63 + 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#" )
kelvin-onlab2c4342a2015-01-28 15:59:53 -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
kelvin-onlab2c4342a2015-01-28 15:59:53 -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 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -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
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800134 def generateExpectedSingleRouteIntent( self, prefix, nextHop, nextHopMac,
135 sdnipData ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800136
kelvin-onlab2c4342a2015-01-28 15:59:53 -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-onlab2c4342a2015-01-28 15:59:53 -0800140 if peer[ 'ipAddress' ] == nextHop:
141 egress = "of:" + str(
142 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
143 + str( peer[ 'attachmentPort' ] )
144 for peer in sdnipData[ 'bgpPeers' ]:
145 if not peer[ 'ipAddress' ] == nextHop:
146 ingress = "of:" + str(
147 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
148 + str( peer[ 'attachmentPort' ] )
149 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
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800158 intent = egress + "/" + str( sorted( ingresses ) ) + "/" + \
159 selector + "/" + treatment
pingping-lin6f6332e2014-11-19 19:13:58 -0800160 return intent
161
kelvin-onlab2c4342a2015-01-28 15:59:53 -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(
kelvin-onlab2c4342a2015-01-28 15:59:53 -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-lin6f6332e2014-11-19 19:13:58 -0800193
194 # This method extracts all actual route intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 def extractActualRouteIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800196 intents = []
197 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800198 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
199 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800200
kelvin-onlabd3b64892015-01-20 13:26:24 -0800201 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800202 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800203 continue
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800204 if intent[ 'type' ] == "MultiPointToSinglePointIntent" \
205 and intent[ 'state' ] == 'INSTALLED':
206 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" \
207 + str( intent[ 'egress' ][ 'port' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800208 ingress = []
kelvin-onlabbbe46482015-01-16 10:44:28 -0800209 for attachmentPoint in intent[ 'ingress' ]:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800210 ingress.append(
211 str( attachmentPoint[ 'device' ] ) + ":"
212 + str( attachmentPoint[ 'port' ] ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800213
kelvin-onlabbbe46482015-01-16 10:44:28 -0800214 selector = intent[ 'selector' ].replace(
215 "[", "" ).replace( "]", "" ).replace( " ", "" )
216 if str( selector ).startswith( "IPV4" ):
217 str1, str2 = str( selector ).split( "," )
pingping-linc6b86fa2014-12-01 16:18:10 -0800218 selector = str2 + "," + str1
219
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800220 intent = egress + "/" + str( sorted( ingress ) ) + "/" + \
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 selector + "/" + intent[ 'treatment' ]
kelvin-onlabbbe46482015-01-16 10:44:28 -0800222 intents.append( intent )
223 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800224
225 # This method extracts all actual BGP intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800226 def extractActualBgpIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800227 intents = []
228 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
230 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800231
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800233 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800234 continue
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800235 if intent[ 'type' ] == "PointToPointIntent" \
236 and "protocol=6" in str( intent[ 'selector' ] ):
237 ingress = str( intent[ 'ingress' ][ 'device' ] ) + ":" \
238 + str( intent[ 'ingress' ][ 'port' ] )
239 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + \
240 str( intent[ 'egress' ][ 'port' ] )
241 selector = str( intent[ 'selector' ] ).replace( " ", "" )\
242 .replace( "[", "" ).replace( "]", "" ).split( "," )
243 intent = ingress + "/" + egress + "/" + \
244 str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800245 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800246
kelvin-onlabbbe46482015-01-16 10:44:28 -0800247 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800248
kelvin-onlabbbe46482015-01-16 10:44:28 -0800249 # This method generates a single point to single point intent(
250 # PointToPointIntent ) for BGP path
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 def generateExpectedBgpIntents( self, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800252 from operator import eq
253
kelvin-onlabd3b64892015-01-20 13:26:24 -0800254 sdnipJsonFile = open( sdnipJsonFilePath ).read()
255 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800256
257 intents = []
pingping-linc6b86fa2014-12-01 16:18:10 -0800258 bgpPeerAttachmentPoint = ""
kelvin-onlabbbe46482015-01-16 10:44:28 -0800259 bgpSpeakerAttachmentPoint = "of:" + str(
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800260 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] )\
261 .replace( ":", "" ) + ":" \
262 + str( sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800263 for peer in sdnipData[ 'bgpPeers' ]:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800264 bgpPeerAttachmentPoint = "of:" \
265 + str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) \
266 + ":" + str( peer[ 'attachmentPort' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800267 # find out the BGP speaker IP address for this BGP peer
pingping-linc6b86fa2014-12-01 16:18:10 -0800268 bgpSpeakerIpAddress = ""
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800269 for interfaceAddress in \
270 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'interfaceAddresses' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 # if eq( interfaceAddress[ 'interfaceDpid' ],sdnipData[
kelvin-onlabbbe46482015-01-16 10:44:28 -0800272 # 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ) and eq(
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800273 # interfaceAddress[ 'interfacePort' ], sdnipData[ 'bgpSpeakers'
274 # ][ 0 ][ 'attachmentPort' ] ):
275 if eq( interfaceAddress[ 'interfaceDpid' ],
276 peer[ 'attachmentDpid' ] ) \
277 and eq( interfaceAddress[ 'interfacePort' ],
kelvin-onlabd3b64892015-01-20 13:26:24 -0800278 peer[ 'attachmentPort' ] ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800279 bgpSpeakerIpAddress = interfaceAddress[ 'ipAddress' ]
pingping-lin6f6332e2014-11-19 19:13:58 -0800280 break
281 else:
282 continue
283
kelvin-onlabbbe46482015-01-16 10:44:28 -0800284 # from bgpSpeakerAttachmentPoint to bgpPeerAttachmentPoint
285 # direction
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800286 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
287 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
288 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
289 TCP_DST{tcpPort=179}"
290 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
291 .replace( "]", "" ).split( "," )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800292 intent = bgpSpeakerAttachmentPoint + "/" + \
293 bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
294 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800295
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800296 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
297 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
298 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
299 TCP_SRC{tcpPort=179}"
300 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
301 .replace( "]", "" ).split( "," )
302 intent = bgpSpeakerAttachmentPoint + "/" \
303 + bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800304 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800305
kelvin-onlabbbe46482015-01-16 10:44:28 -0800306 # from bgpPeerAttachmentPoint to bgpSpeakerAttachmentPoint
307 # direction
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800308 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
309 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
310 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
311 TCP_DST{tcpPort=179}"
312 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
313 .replace( "]", "" ).split( "," )
314 intent = bgpPeerAttachmentPoint + "/" \
315 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800316 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800317
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800318 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
319 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
320 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
321 TCP_SRC{tcpPort=179}"
322 selector = selectorStr.replace( " ", "" ).replace( "[", "" )\
323 .replace( "]", "" ).split( "," )
324 intent = bgpPeerAttachmentPoint + "/" \
325 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800326 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800327
kelvin-onlabbbe46482015-01-16 10:44:28 -0800328 return sorted( intents )
pingping-linc6b86fa2014-12-01 16:18:10 -0800329
kelvin-onlabd3b64892015-01-20 13:26:24 -0800330 def addRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800331 main.log.info( "I am in add_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800332
kelvin-onlabd3b64892015-01-20 13:26:24 -0800333 routesAdded = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800334 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800335 self.handle.sendline( "" )
336 # self.handle.expect( "config-router" )
337 self.handle.expect( "config-router", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800338 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800339 main.log.warn( "Probably not in config-router mode!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800340 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800341 main.log.info( "Start to add routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800342
kelvin-onlabbbe46482015-01-16 10:44:28 -0800343 for i in range( 0, len( routes ) ):
344 routeCmd = "network " + routes[ i ]
pingping-lin8b306ac2014-11-17 18:13:51 -0800345 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800346 self.handle.sendline( routeCmd )
347 self.handle.expect( "bgpd", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800348 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800349 main.log.warn( "Failed to add route" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800350 self.disconnect()
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800351 # waitTimer = 1.00 / routeRate
352 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800353 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800354 main.log.info( "Finished adding routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800355 return main.TRUE
356 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800357
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 def deleteRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800359 main.log.info( "I am in delete_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800360
kelvin-onlabd3b64892015-01-20 13:26:24 -0800361 routesAdded = 0
pingping-linc6b86fa2014-12-01 16:18:10 -0800362 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800363 self.handle.sendline( "" )
364 # self.handle.expect( "config-router" )
365 self.handle.expect( "config-router", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800366 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800367 main.log.warn( "Probably not in config-router mode!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800368 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800369 main.log.info( "Start to delete routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800370
kelvin-onlabbbe46482015-01-16 10:44:28 -0800371 for i in range( 0, len( routes ) ):
372 routeCmd = "no network " + routes[ i ]
pingping-linc6b86fa2014-12-01 16:18:10 -0800373 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800374 self.handle.sendline( routeCmd )
375 self.handle.expect( "bgpd", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800376 except:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800377 main.log.warn( "Failed to delete route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800378 self.disconnect()
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800379 # waitTimer = 1.00 / routeRate
380 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800381 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800382 main.log.info( "Finished deleting routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800383 return main.TRUE
384 return main.FALSE
385
kelvin-onlab08679eb2015-01-21 16:11:48 -0800386 def pingTest( self, ip_address, pingTestFile, pingTestResultFile ):
387 main.log.info( "Start the ping test on host:" + str( ip_address ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800388
kelvin-onlabbbe46482015-01-16 10:44:28 -0800389 self.name = self.options[ 'name' ]
390 self.handle = super( QuaggaCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800391 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -0800392 port=self.port, pwd=self.pwd )
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800393 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
394 + str( self.ip_address ) + ";" + str( self.port )
395 + ";" + str( self.pwd ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800396
397 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800398 # self.handle.expect( "" )
399 # self.handle.expect( "\$" )
kelvin-onlab08679eb2015-01-21 16:11:48 -0800400 main.log.info( "I in host " + str( ip_address ) )
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800401 main.log.info( pingTestFile + " > " + pingTestResultFile + " &" )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800402 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800403 pingTestFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800404 " > " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800405 pingTestResultFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800406 " &" )
407 self.handle.expect( "\$", timeout=60 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800408 handle = self.handle.before
409
410 return handle
411 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800412 main.log.info( "NO HANDLE" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800413 return main.FALSE
414
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800415 # Please use the generateRoutes plus addRoutes instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800416 def addRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700417 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800418 self.handle.sendline( "" )
419 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700420 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800421 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700422 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800423 main.log.info( "Adding Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800424 j = 0
425 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700426 while numRoutes > 255:
427 numRoutes = numRoutes - 255
428 j = j + 1
429 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 routesAdded = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700431 if numRoutes > 255:
432 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800433 for m in range( 1, j + 1 ):
434 for n in range( 1, numRoutes + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800435 network = str( net ) + "." + str( m ) + "." + str( n ) \
436 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700437 routeCmd = "network " + network
438 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800439 self.handle.sendline( routeCmd )
440 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700441 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800442 main.log.warn( "failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800443 self.disconnect()
444 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800445 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800446 routesAdded = routesAdded + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800447 for d in range( j + 1, j + 2 ):
448 for e in range( 1, k + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800449 network = str( net ) + "." + str( d ) + "." + str( e ) \
450 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700451 routeCmd = "network " + network
452 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800453 self.handle.sendline( routeCmd )
454 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700455 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800456 main.log.warn( "failed to add route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700457 self.disconnect
pingping-linc6b86fa2014-12-01 16:18:10 -0800458 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800459 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800460 routesAdded = routesAdded + 1
461 if routesAdded == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700462 return main.TRUE
463 return main.FALSE
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800464
465 # Please use deleteRoutes method instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800466 def delRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700467 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800468 self.handle.sendline( "" )
469 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700470 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800471 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700472 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800473 main.log.info( "Deleting Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800474 j = 0
475 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700476 while numRoutes > 255:
477 numRoutes = numRoutes - 255
478 j = j + 1
479 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 routesDeleted = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700481 if numRoutes > 255:
482 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800483 for m in range( 1, j + 1 ):
484 for n in range( 1, numRoutes + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800485 network = str( net ) + "." + str( m ) + "." + str( n ) \
486 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700487 routeCmd = "no network " + network
488 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800489 self.handle.sendline( routeCmd )
490 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700491 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800492 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700493 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800494 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800495 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800496 routesDeleted = routesDeleted + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800497 for d in range( j + 1, j + 2 ):
498 for e in range( 1, k + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800499 network = str( net ) + "." + str( d ) + "." + str( e ) \
500 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700501 routeCmd = "no network " + network
502 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800503 self.handle.sendline( routeCmd )
504 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700505 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800506 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700507 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800508 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800509 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800510 routesDeleted = routesDeleted + 1
511 if routesDeleted == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700512 return main.TRUE
513 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800514
kelvin-onlabd3b64892015-01-20 13:26:24 -0800515 def checkRoutes( self, brand, ip, user, pw ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800516 def pronto( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700517 print "Connecting to Pronto switch"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800518 child = pexpect.spawn( "telnet " + ip )
519 i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700520 if i == 0:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800521 print "user_name and password required. Passing login info."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800522 child.sendline( user )
523 child.expect( "Password:" )
524 child.sendline( passwd )
525 child.expect( "CLI#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700526 print "Logged in, getting flowtable."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800527 child.sendline( "flowtable brief" )
528 for t in range( 9 ):
timlindbergef8d55d2013-09-27 12:50:13 -0700529 t2 = 9 - t
kelvin-onlabbbe46482015-01-16 10:44:28 -0800530 print "\r" + str( t2 )
531 sys.stdout.write( "\033[F" )
532 time.sleep( 1 )
timlindbergef8d55d2013-09-27 12:50:13 -0700533 print "Scanning flowtable"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800534 child.expect( "Flow table show" )
timlindbergef8d55d2013-09-27 12:50:13 -0700535 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800536 while True:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800537 i = child.expect( [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
538 'CLI#', pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700539 if i == 0:
540 count = count + 1
541 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800542 print "Pronto flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700543 break
544 else:
545 break
kelvin-onlabbbe46482015-01-16 10:44:28 -0800546
547 def cisco( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700548 print "Establishing Cisco switch connection"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800549 child = pexpect.spawn( "ssh " + user + "@" + ip )
550 i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700551 if i == 0:
552 print "Password required. Passing now."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800553 child.sendline( passwd )
554 child.expect( "#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700555 print "Logged in. Retrieving flow table then counting flows."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800556 child.sendline( "show openflow switch all flows all" )
557 child.expect( "Logical Openflow Switch" )
timlindbergef8d55d2013-09-27 12:50:13 -0700558 print "Flow table retrieved. Counting flows"
559 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800560 while True:
561 i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700562 if i == 0:
563 count = count + 1
564 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800565 print "Cisco flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700566 break
567 else:
568 break
569 if brand == "pronto" or brand == "PRONTO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800570 pronto( ip, user, passwd )
pingping-linc6b86fa2014-12-01 16:18:10 -0800571 # elif brand == "cisco" or brand == "CISCO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800572 # cisco( ip,user,passwd )
573
574 def disconnect( self ):
575 """
576 Called when Test is complete to disconnect the Quagga handle.
577 """
timlindbergef8d55d2013-09-27 12:50:13 -0700578 response = ''
579 try:
580 self.handle.close()
581 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800582 main.log.error( "Connection failed to the host" )
timlindbergef8d55d2013-09-27 12:50:13 -0700583 response = main.FALSE
584 return response
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800585