blob: e0a43385c34de56d101ad8032d7d2328e5245afb [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
sanghoshin29e6a472015-02-27 12:55:06 -0800415 def pingTestAndCheckAllPass( self, ip_address):
416 main.log.info( "Start the ping test on host:" + str( ip_address ) )
417
418 self.name = self.options[ 'name' ]
419 self.handle = super( QuaggaCliDriver, self ).connect(
420 user_name=self.user_name, ip_address=ip_address,
421 port=self.port, pwd=self.pwd )
422 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
423 + str( self.ip_address ) + ";" + str( self.port )
424 + ";" + str( self.pwd ) )
425
426 testPass = main.TRUE
427
428 if self.handle:
429 # self.handle.expect( "" )
430 # self.handle.expect( "\$" )
431 main.log.info( "I in host " + str( ip_address ) )
432
433 # Ping to 3.0.x.1 is just for sanity check. It always succeeds.
434 for m in range( 3, 6 ):
435 for n in range( 1, 11 ):
436 hostIp = str( m ) + ".0." + str( n ) + ".1"
437 main.log.info( "Ping to " + hostIp )
438 try:
439 self.handle.sendline("ping -c 1 " + hostIp)
440 self.handle.expect( "64 bytes from", timeout=1 )
441 except:
442 main.log.warn("Ping error")
443 testPass = main.FALSE
444
445 return testPass
446 else:
447 main.log.info( "NO HANDLE" )
448 return main.FALSE
449
450 def pingTestAndCheckAllFail( self, ip_address):
451 main.log.info( "Start the ping test on host:" + str( ip_address ) )
452
453 self.name = self.options[ 'name' ]
454 self.handle = super( QuaggaCliDriver, self ).connect(
455 user_name=self.user_name, ip_address=ip_address,
456 port=self.port, pwd=self.pwd )
457 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
458 + str( self.ip_address ) + ";" + str( self.port )
459 + ";" + str( self.pwd ) )
460
461 testPass = main.TRUE
462
463 if self.handle:
464 # self.handle.expect( "" )
465 # self.handle.expect( "\$" )
466 main.log.info( "I in host " + str( ip_address ) )
467
468 for m in range( 4, 6 ):
469 for n in range( 1, 11 ):
470 hostIp = str( m ) + ".0." + str( n ) + ".1"
471 main.log.info( "Ping to " + hostIp )
472 try:
473 self.handle.sendline("ping -c 1 " + hostIp)
474 self.handle.expect( "64 bytes from", timeout=1 )
475 testPass = main.FALSE
476 except:
477 main.log.warn("Ping error")
478
479 return testPass
480 else:
481 main.log.info( "NO HANDLE" )
482 return main.FALSE
483
484
485
486
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800487 # Please use the generateRoutes plus addRoutes instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800488 def addRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700489 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800490 self.handle.sendline( "" )
491 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700492 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800493 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700494 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800495 main.log.info( "Adding Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800496 j = 0
497 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700498 while numRoutes > 255:
499 numRoutes = numRoutes - 255
500 j = j + 1
501 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 routesAdded = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700503 if numRoutes > 255:
504 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800505 for m in range( 1, j + 1 ):
506 for n in range( 1, numRoutes + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800507 network = str( net ) + "." + str( m ) + "." + str( n ) \
508 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700509 routeCmd = "network " + network
510 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800511 self.handle.sendline( routeCmd )
512 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700513 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800514 main.log.warn( "failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800515 self.disconnect()
516 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800517 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800518 routesAdded = routesAdded + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800519 for d in range( j + 1, j + 2 ):
520 for e in range( 1, k + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800521 network = str( net ) + "." + str( d ) + "." + str( e ) \
522 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700523 routeCmd = "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 add 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 routesAdded = routesAdded + 1
533 if routesAdded == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700534 return main.TRUE
535 return main.FALSE
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800536
537 # Please use deleteRoutes method instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800538 def delRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700539 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800540 self.handle.sendline( "" )
541 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700542 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800543 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700544 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800545 main.log.info( "Deleting Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800546 j = 0
547 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700548 while numRoutes > 255:
549 numRoutes = numRoutes - 255
550 j = j + 1
551 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 routesDeleted = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700553 if numRoutes > 255:
554 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800555 for m in range( 1, j + 1 ):
556 for n in range( 1, numRoutes + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800557 network = str( net ) + "." + str( m ) + "." + str( n ) \
558 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700559 routeCmd = "no network " + network
560 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800561 self.handle.sendline( routeCmd )
562 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700563 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800564 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700565 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800566 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800567 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 routesDeleted = routesDeleted + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800569 for d in range( j + 1, j + 2 ):
570 for e in range( 1, k + 1 ):
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800571 network = str( net ) + "." + str( d ) + "." + str( e ) \
572 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700573 routeCmd = "no network " + network
574 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800575 self.handle.sendline( routeCmd )
576 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700577 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800578 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700579 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800580 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800581 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 routesDeleted = routesDeleted + 1
583 if routesDeleted == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700584 return main.TRUE
585 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800586
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 def checkRoutes( self, brand, ip, user, pw ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800588 def pronto( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700589 print "Connecting to Pronto switch"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800590 child = pexpect.spawn( "telnet " + ip )
591 i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700592 if i == 0:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800593 print "user_name and password required. Passing login info."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800594 child.sendline( user )
595 child.expect( "Password:" )
596 child.sendline( passwd )
597 child.expect( "CLI#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700598 print "Logged in, getting flowtable."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800599 child.sendline( "flowtable brief" )
600 for t in range( 9 ):
timlindbergef8d55d2013-09-27 12:50:13 -0700601 t2 = 9 - t
kelvin-onlabbbe46482015-01-16 10:44:28 -0800602 print "\r" + str( t2 )
603 sys.stdout.write( "\033[F" )
604 time.sleep( 1 )
timlindbergef8d55d2013-09-27 12:50:13 -0700605 print "Scanning flowtable"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800606 child.expect( "Flow table show" )
timlindbergef8d55d2013-09-27 12:50:13 -0700607 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800608 while True:
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800609 i = child.expect( [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
610 'CLI#', pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700611 if i == 0:
612 count = count + 1
613 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800614 print "Pronto flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700615 break
616 else:
617 break
kelvin-onlabbbe46482015-01-16 10:44:28 -0800618
619 def cisco( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700620 print "Establishing Cisco switch connection"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800621 child = pexpect.spawn( "ssh " + user + "@" + ip )
622 i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700623 if i == 0:
624 print "Password required. Passing now."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800625 child.sendline( passwd )
626 child.expect( "#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700627 print "Logged in. Retrieving flow table then counting flows."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800628 child.sendline( "show openflow switch all flows all" )
629 child.expect( "Logical Openflow Switch" )
timlindbergef8d55d2013-09-27 12:50:13 -0700630 print "Flow table retrieved. Counting flows"
631 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800632 while True:
633 i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700634 if i == 0:
635 count = count + 1
636 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800637 print "Cisco flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700638 break
639 else:
640 break
641 if brand == "pronto" or brand == "PRONTO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800642 pronto( ip, user, passwd )
pingping-linc6b86fa2014-12-01 16:18:10 -0800643 # elif brand == "cisco" or brand == "CISCO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800644 # cisco( ip,user,passwd )
645
646 def disconnect( self ):
647 """
648 Called when Test is complete to disconnect the Quagga handle.
649 """
timlindbergef8d55d2013-09-27 12:50:13 -0700650 response = ''
651 try:
652 self.handle.close()
653 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800654 main.log.error( "Connection failed to the host" )
timlindbergef8d55d2013-09-27 12:50:13 -0700655 response = main.FALSE
656 return response
kelvin-onlab2c4342a2015-01-28 15:59:53 -0800657