blob: f391e3aa638a15cb3c26230f4033feef2f88b179 [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 sys
timlindbergef8d55d2013-09-27 12:50:13 -07006import json
kelvin-onlabbbe46482015-01-16 10:44:28 -08007sys.path.append( "../" )
timlindbergef8d55d2013-09-27 12:50:13 -07008from drivers.common.clidriver import CLI
9
timlindbergef8d55d2013-09-27 12:50:13 -070010
kelvin-onlabbbe46482015-01-16 10:44:28 -080011class QuaggaCliDriver( CLI ):
12
13 def __init__( self ):
14 super( CLI, self ).__init__()
timlindbergef8d55d2013-09-27 12:50:13 -070015
pingping-linc6b86fa2014-12-01 16:18:10 -080016 # TODO: simplify this method
kelvin-onlabbbe46482015-01-16 10:44:28 -080017 def connect( self, **connectargs ):
timlindbergef8d55d2013-09-27 12:50:13 -070018 for key in connectargs:
kelvin-onlabbbe46482015-01-16 10:44:28 -080019 vars( self )[ key ] = connectargs[ key ]
pingping-lin763ee042015-05-20 17:45:30 -070020 self.name = self.options[ 'name' ]
21 self.handle = super( QuaggaCliDriver, self ).connect(
22 user_name=self.user_name,
23 ip_address="127.0.0.1",
24 port=self.port,
25 pwd=self.pwd )
26 if self.handle:
27 return self.handle
28 else:
29 main.log.info( "NO HANDLE" )
30 return main.FALSE
31
pingping-linc6b86fa2014-12-01 16:18:10 -080032
pingping-lin763ee042015-05-20 17:45:30 -070033 def connectQuagga( self ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080034 self.name = self.options[ 'name' ]
35 # self.handle = super( QuaggaCliDriver,self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080036 # user_name=self.user_name, ip_address=self.ip_address,port=self.port,
kelvin-onlabbbe46482015-01-16 10:44:28 -080037 # pwd=self.pwd )
pingping-lin4e7b0d32015-01-27 18:06:22 -080038 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080039 user_name=self.user_name,
40 ip_address="1.1.1.1",
41 port=self.port,
42 pwd=self.pwd )
pingping-lina600d9b2015-01-30 13:57:26 -080043 #main.log.info( "connect parameters:" + str( self.user_name ) + ";"
44 # + str( self.ip_address ) + ";" + str( self.port )
45 # + ";" + str(self.pwd ) )
timlindbergef8d55d2013-09-27 12:50:13 -070046
pingping-linc6b86fa2014-12-01 16:18:10 -080047 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080048 # self.handle.expect( "",timeout=10 )
49 # self.handle.expect( "\$",timeout=10 )
50 self.handle.sendline( "telnet localhost 2605" )
51 # self.handle.expect( "Password:", timeout=5 )
52 self.handle.expect( "Password:" )
53 self.handle.sendline( "hello" )
54 # self.handle.expect( "bgpd", timeout=5 )
55 self.handle.expect( "bgpd" )
56 self.handle.sendline( "enable" )
57 # self.handle.expect( "bgpd#", timeout=5 )
58 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -070059 return self.handle
kelvin-onlabbbe46482015-01-16 10:44:28 -080060 else:
61 main.log.info( "NO HANDLE" )
timlindbergef8d55d2013-09-27 12:50:13 -070062 return main.FALSE
63
pingping-linc1c696e2015-01-27 13:46:44 -080064 def loginQuagga( self, ip_address ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080065 self.name = self.options[ 'name' ]
66 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080067 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -080068 port=self.port, pwd=self.pwd )
pingping-linc1c696e2015-01-27 13:46:44 -080069 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
pingping-lin4e7b0d32015-01-27 18:06:22 -080070 + str( self.ip_address ) + ";" + str( self.port )
71 + ";" + str( self.pwd ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080072
73 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080074 # self.handle.expect( "" )
75 # self.handle.expect( "\$" )
76 self.handle.sendline( "telnet localhost 2605" )
77 # self.handle.expect( "Password:", timeout=5 )
78 self.handle.expect( "Password:" )
79 self.handle.sendline( "hello" )
80 # self.handle.expect( "bgpd", timeout=5 )
81 self.handle.expect( "bgpd" )
82 self.handle.sendline( "enable" )
83 # self.handle.expect( "bgpd#", timeout=5 )
84 self.handle.expect( "bgpd#" )
pingping-linc1c696e2015-01-27 13:46:44 -080085 main.log.info( "I am in quagga on host " + str( ip_address ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080086
87 return self.handle
88 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -080089 main.log.info( "NO HANDLE" )
pingping-lin8b306ac2014-11-17 18:13:51 -080090 return main.FALSE
91
kelvin-onlabd3b64892015-01-20 13:26:24 -080092 def enterConfig( self, asn ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080093 main.log.info( "I am in enter_config method!" )
timlindbergef8d55d2013-09-27 12:50:13 -070094 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -080095 self.handle.sendline( "" )
96 self.handle.expect( "bgpd#" )
pingping-lin763ee042015-05-20 17:45:30 -070097 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -080098 main.log.warn( "Probably not currently in enable mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -070099 self.disconnect()
100 return main.FALSE
kelvin-onlabbbe46482015-01-16 10:44:28 -0800101 self.handle.sendline( "configure terminal" )
102 self.handle.expect( "config", timeout=5 )
103 routerAS = "router bgp " + str( asn )
timlindbergef8d55d2013-09-27 12:50:13 -0700104 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800105 self.handle.sendline( routerAS )
106 self.handle.expect( "config-router", timeout=5 )
timlindbergef8d55d2013-09-27 12:50:13 -0700107 return main.TRUE
pingping-lin763ee042015-05-20 17:45:30 -0700108 except Exception:
timlindbergef8d55d2013-09-27 12:50:13 -0700109 return main.FALSE
pingping-lin8b306ac2014-11-17 18:13:51 -0800110
kelvin-onlabd3b64892015-01-20 13:26:24 -0800111 def generatePrefixes( self, net, numRoutes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800112 main.log.info( "I am in generate_prefixes method!" )
pingping-lin6f6332e2014-11-19 19:13:58 -0800113
pingping-lin4e7b0d32015-01-27 18:06:22 -0800114 # each IP prefix is composed by "net" + "." + m + "." + n + "." + x
pingping-lin8b306ac2014-11-17 18:13:51 -0800115 # the length of each IP prefix is 24
116 routes = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800117 routesGen = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800118 m = numRoutes / 256
119 n = numRoutes % 256
120
kelvin-onlabbbe46482015-01-16 10:44:28 -0800121 for i in range( 0, m ):
122 for j in range( 0, 256 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800123 network = str( net ) + "." + str( i ) + "." + str( j ) \
124 + ".0/24"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800125 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800126 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800127
kelvin-onlabbbe46482015-01-16 10:44:28 -0800128 for j in range( 0, n ):
129 network = str( net ) + "." + str( m ) + "." + str( j ) + ".0/24"
130 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800131 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800132
kelvin-onlabd3b64892015-01-20 13:26:24 -0800133 if routesGen == numRoutes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800134 main.log.info( "Successfully generated " + str( numRoutes )
135 + " prefixes!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800136 return routes
137 return main.FALSE
pingping-lin6f6332e2014-11-19 19:13:58 -0800138
kelvin-onlabbbe46482015-01-16 10:44:28 -0800139 # This method generates a multiple to single point intent(
140 # MultiPointToSinglePointIntent ) for a given route
pingping-lin4e7b0d32015-01-27 18:06:22 -0800141 def generateExpectedSingleRouteIntent( self, prefix, nextHop, nextHopMac,
142 sdnipData ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800143
pingping-linc1c696e2015-01-27 13:46:44 -0800144 ingresses = []
pingping-lin6f6332e2014-11-19 19:13:58 -0800145 egress = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800146 for peer in sdnipData[ 'bgpPeers' ]:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800147 if peer[ 'ipAddress' ] == nextHop:
pingping-linc1c696e2015-01-27 13:46:44 -0800148 egress = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800149 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
150 + str( peer[ 'attachmentPort' ] )
pingping-linc1c696e2015-01-27 13:46:44 -0800151 for peer in sdnipData[ 'bgpPeers' ]:
152 if not peer[ 'ipAddress' ] == nextHop:
153 ingress = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800154 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
155 + str( peer[ 'attachmentPort' ] )
pingping-linc1c696e2015-01-27 13:46:44 -0800156 if not ingress == egress and ingress not in ingresses:
157 ingresses.append( ingress )
158 # ingresses.append( "of:" + str( peer[ 'attachmentDpid' ]
159 # ).replace( ":", "" ) + ":" + str( peer[ 'attachmentPort'
160 # ] ) )
pingping-lin6f6332e2014-11-19 19:13:58 -0800161
pingping-linc6b86fa2014-12-01 16:18:10 -0800162 selector = "ETH_TYPE{ethType=800},IPV4_DST{ip=" + prefix + "}"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800163 treatment = "[ETH_DST{mac=" + str( nextHopMac ) + "}]"
pingping-lin6f6332e2014-11-19 19:13:58 -0800164
pingping-lin4e7b0d32015-01-27 18:06:22 -0800165 intent = egress + "/" + str( sorted( ingresses ) ) + "/" + \
166 selector + "/" + treatment
pingping-lin6f6332e2014-11-19 19:13:58 -0800167 return intent
168
pingping-lin4e7b0d32015-01-27 18:06:22 -0800169 def generateExpectedOnePeerRouteIntents( self, prefixes, nextHop,
170 nextHopMac, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800171 intents = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800172 sdnipJsonFile = open( sdnipJsonFilePath ).read()
pingping-lin6f6332e2014-11-19 19:13:58 -0800173
kelvin-onlabd3b64892015-01-20 13:26:24 -0800174 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800175
176 for prefix in prefixes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800177 intents.append(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800178 self.generateExpectedSingleRouteIntent(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800179 prefix, nextHop, nextHopMac, sdnipData ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800180 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800181
182 # TODO
183 # This method generates all expected route intents for all BGP peers
kelvin-onlabd3b64892015-01-20 13:26:24 -0800184 def generateExpectedRouteIntents( self ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800185 intents = []
186 return intents
187
188 # This method extracts all actual routes from ONOS CLI
pingping-linb2a86582015-02-02 16:18:59 -0800189 def extractActualRoutesOneDotZero( self, getRoutesResult ):
kelvin-onlabd3b64892015-01-20 13:26:24 -0800190 routesJsonObj = json.loads( getRoutesResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800191
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 allRoutesActual = []
pingping-lin763ee042015-05-20 17:45:30 -0700193 for route in routesJsonObj['routes4']:
194 if 'prefix' in route:
195 if route[ 'prefix' ] == '172.16.10.0/24':
196 continue
197 allRoutesActual.append(
198 route[ 'prefix' ] + "/" + route[ 'nextHop' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800199
kelvin-onlabd3b64892015-01-20 13:26:24 -0800200 return sorted( allRoutesActual )
pingping-linb2a86582015-02-02 16:18:59 -0800201
202 def extractActualRoutesMaster( self, getRoutesResult ):
pingping-lina600d9b2015-01-30 13:57:26 -0800203 routesJsonObj = json.loads( getRoutesResult )
204
205 allRoutesActual = []
206 for route in routesJsonObj['routes4']:
207 if route[ 'prefix' ] == '172.16.10.0/24':
208 continue
209 allRoutesActual.append(
210 route[ 'prefix' ] + "/" + route[ 'nextHop' ] )
211
212 return sorted( allRoutesActual )
pingping-lin6f6332e2014-11-19 19:13:58 -0800213
214 # This method extracts all actual route intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 def extractActualRouteIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800216 intents = []
217 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
219 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800220
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800222 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800223 continue
pingping-lin4e7b0d32015-01-27 18:06:22 -0800224 if intent[ 'type' ] == "MultiPointToSinglePointIntent" \
225 and intent[ 'state' ] == 'INSTALLED':
226 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" \
227 + str( intent[ 'egress' ][ 'port' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800228 ingress = []
kelvin-onlabbbe46482015-01-16 10:44:28 -0800229 for attachmentPoint in intent[ 'ingress' ]:
pingping-linc1c696e2015-01-27 13:46:44 -0800230 ingress.append(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800231 str( attachmentPoint[ 'device' ] ) + ":"
232 + str( attachmentPoint[ 'port' ] ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800233
kelvin-onlabbbe46482015-01-16 10:44:28 -0800234 selector = intent[ 'selector' ].replace(
235 "[", "" ).replace( "]", "" ).replace( " ", "" )
236 if str( selector ).startswith( "IPV4" ):
237 str1, str2 = str( selector ).split( "," )
pingping-linc6b86fa2014-12-01 16:18:10 -0800238 selector = str2 + "," + str1
239
pingping-lin4e7b0d32015-01-27 18:06:22 -0800240 intent = egress + "/" + str( sorted( ingress ) ) + "/" + \
241 selector + "/" + intent[ 'treatment' ]
kelvin-onlabbbe46482015-01-16 10:44:28 -0800242 intents.append( intent )
243 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800244
245 # This method extracts all actual BGP intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 def extractActualBgpIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800247 intents = []
248 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800249 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
250 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800251
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800253 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800254 continue
pingping-lin4e7b0d32015-01-27 18:06:22 -0800255 if intent[ 'type' ] == "PointToPointIntent" \
256 and "protocol=6" in str( intent[ 'selector' ] ):
257 ingress = str( intent[ 'ingress' ][ 'device' ] ) + ":" \
258 + str( intent[ 'ingress' ][ 'port' ] )
259 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + \
260 str( intent[ 'egress' ][ 'port' ] )
261 selector = str( intent[ 'selector' ] ).replace( " ", "" )\
262 .replace( "[", "" ).replace( "]", "" ).split( "," )
263 intent = ingress + "/" + egress + "/" + \
264 str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800265 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800266
kelvin-onlabbbe46482015-01-16 10:44:28 -0800267 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800268
kelvin-onlabbbe46482015-01-16 10:44:28 -0800269 # This method generates a single point to single point intent(
270 # PointToPointIntent ) for BGP path
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 def generateExpectedBgpIntents( self, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800272 from operator import eq
273
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 sdnipJsonFile = open( sdnipJsonFilePath ).read()
275 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800276
277 intents = []
pingping-linc6b86fa2014-12-01 16:18:10 -0800278 bgpPeerAttachmentPoint = ""
kelvin-onlabbbe46482015-01-16 10:44:28 -0800279 bgpSpeakerAttachmentPoint = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800280 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] )\
281 .replace( ":", "" ) + ":" \
282 + str( sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 for peer in sdnipData[ 'bgpPeers' ]:
pingping-lin4e7b0d32015-01-27 18:06:22 -0800284 bgpPeerAttachmentPoint = "of:" \
285 + str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) \
286 + ":" + str( peer[ 'attachmentPort' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800287 # find out the BGP speaker IP address for this BGP peer
pingping-linc6b86fa2014-12-01 16:18:10 -0800288 bgpSpeakerIpAddress = ""
pingping-lin4e7b0d32015-01-27 18:06:22 -0800289 for interfaceAddress in \
290 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'interfaceAddresses' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 # if eq( interfaceAddress[ 'interfaceDpid' ],sdnipData[
kelvin-onlabbbe46482015-01-16 10:44:28 -0800292 # 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ) and eq(
pingping-linc1c696e2015-01-27 13:46:44 -0800293 # interfaceAddress[ 'interfacePort' ], sdnipData[ 'bgpSpeakers'
294 # ][ 0 ][ 'attachmentPort' ] ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800295 if eq( interfaceAddress[ 'interfaceDpid' ],
296 peer[ 'attachmentDpid' ] ) \
297 and eq( interfaceAddress[ 'interfacePort' ],
298 peer[ 'attachmentPort' ] ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800299 bgpSpeakerIpAddress = interfaceAddress[ 'ipAddress' ]
pingping-lin6f6332e2014-11-19 19:13:58 -0800300 break
301 else:
302 continue
303
kelvin-onlabbbe46482015-01-16 10:44:28 -0800304 # from bgpSpeakerAttachmentPoint to bgpPeerAttachmentPoint
305 # direction
pingping-lin4e7b0d32015-01-27 18:06:22 -0800306 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
307 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
308 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
309 TCP_DST{tcpPort=179}"
310 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
311 .replace( "]", "" ).split( "," )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800312 intent = bgpSpeakerAttachmentPoint + "/" + \
313 bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
314 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800315
pingping-lin4e7b0d32015-01-27 18:06:22 -0800316 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
317 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
318 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
319 TCP_SRC{tcpPort=179}"
320 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
321 .replace( "]", "" ).split( "," )
322 intent = bgpSpeakerAttachmentPoint + "/" \
323 + bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800324 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800325
kelvin-onlabbbe46482015-01-16 10:44:28 -0800326 # from bgpPeerAttachmentPoint to bgpSpeakerAttachmentPoint
327 # direction
pingping-lin4e7b0d32015-01-27 18:06:22 -0800328 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
329 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
330 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
331 TCP_DST{tcpPort=179}"
332 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
333 .replace( "]", "" ).split( "," )
334 intent = bgpPeerAttachmentPoint + "/" \
335 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800336 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800337
pingping-lin4e7b0d32015-01-27 18:06:22 -0800338 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
339 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
340 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
341 TCP_SRC{tcpPort=179}"
342 selector = selectorStr.replace( " ", "" ).replace( "[", "" )\
343 .replace( "]", "" ).split( "," )
344 intent = bgpPeerAttachmentPoint + "/" \
345 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800346 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800347
kelvin-onlabbbe46482015-01-16 10:44:28 -0800348 return sorted( intents )
pingping-linc6b86fa2014-12-01 16:18:10 -0800349
kelvin-onlabd3b64892015-01-20 13:26:24 -0800350 def addRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800351 main.log.info( "I am in add_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800352
kelvin-onlabd3b64892015-01-20 13:26:24 -0800353 routesAdded = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800354 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800355 self.handle.sendline( "" )
356 # self.handle.expect( "config-router" )
357 self.handle.expect( "config-router", timeout=5 )
pingping-lin763ee042015-05-20 17:45:30 -0700358 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800359 main.log.warn( "Probably not in config-router mode!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800360 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800361 main.log.info( "Start to add routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800362
pingping-lin763ee042015-05-20 17:45:30 -0700363 chunk_size = 20
364
365 if len(routes) > chunk_size:
366 num_iter = (int) (len(routes) / chunk_size)
367 else:
368 num_iter = 1;
369
370 total = 0
371 for n in range( 0, num_iter + 1):
372 routeCmd = ""
373 if (len( routes ) - (n * chunk_size)) >= chunk_size:
374 m = (n + 1) * chunk_size
375 else:
376 m = len( routes )
377 for i in range( n * chunk_size, m ):
378 routeCmd = routeCmd + "network " + routes[ i ] + "\n"
379 total = total + 1
380
381 main.log.info(routeCmd)
pingping-lin8b306ac2014-11-17 18:13:51 -0800382 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800383 self.handle.sendline( routeCmd )
384 self.handle.expect( "bgpd", timeout=5 )
pingping-lin763ee042015-05-20 17:45:30 -0700385 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800386 main.log.warn( "Failed to add route" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800387 self.disconnect()
pingping-lin763ee042015-05-20 17:45:30 -0700388
pingping-linc1c696e2015-01-27 13:46:44 -0800389 # waitTimer = 1.00 / routeRate
pingping-lin763ee042015-05-20 17:45:30 -0700390 main.log.info("Total routes so far " + ((str) (total)) + " wait for 0 sec")
391 #time.sleep( 1 )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800392 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800393 main.log.info( "Finished adding routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800394 return main.TRUE
395 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800396
kelvin-onlabd3b64892015-01-20 13:26:24 -0800397 def deleteRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800398 main.log.info( "I am in delete_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800399
kelvin-onlabd3b64892015-01-20 13:26:24 -0800400 routesAdded = 0
pingping-linc6b86fa2014-12-01 16:18:10 -0800401 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800402 self.handle.sendline( "" )
403 # self.handle.expect( "config-router" )
404 self.handle.expect( "config-router", timeout=5 )
pingping-lin763ee042015-05-20 17:45:30 -0700405 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800406 main.log.warn( "Probably not in config-router mode!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800407 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800408 main.log.info( "Start to delete routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800409
kelvin-onlabbbe46482015-01-16 10:44:28 -0800410 for i in range( 0, len( routes ) ):
411 routeCmd = "no network " + routes[ i ]
pingping-linc6b86fa2014-12-01 16:18:10 -0800412 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800413 self.handle.sendline( routeCmd )
414 self.handle.expect( "bgpd", timeout=5 )
pingping-lin763ee042015-05-20 17:45:30 -0700415 except Exception:
pingping-lin4e7b0d32015-01-27 18:06:22 -0800416 main.log.warn( "Failed to delete route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800417 self.disconnect()
pingping-linc1c696e2015-01-27 13:46:44 -0800418 # waitTimer = 1.00 / routeRate
419 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800420 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800421 main.log.info( "Finished deleting routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800422 return main.TRUE
423 return main.FALSE
424
pingping-linc1c696e2015-01-27 13:46:44 -0800425 def pingTest( self, ip_address, pingTestFile, pingTestResultFile ):
426 main.log.info( "Start the ping test on host:" + str( ip_address ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800427
kelvin-onlabbbe46482015-01-16 10:44:28 -0800428 self.name = self.options[ 'name' ]
429 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -0800430 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -0800431 port=self.port, pwd=self.pwd )
pingping-linc1c696e2015-01-27 13:46:44 -0800432 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
pingping-lin4e7b0d32015-01-27 18:06:22 -0800433 + str( self.ip_address ) + ";" + str( self.port )
434 + ";" + str( self.pwd ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800435
436 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800437 # self.handle.expect( "" )
438 # self.handle.expect( "\$" )
pingping-linc1c696e2015-01-27 13:46:44 -0800439 main.log.info( "I in host " + str( ip_address ) )
440 main.log.info( pingTestFile + " > " + pingTestResultFile + " &" )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800441 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800442 pingTestFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800443 " > " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800444 pingTestResultFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800445 " &" )
446 self.handle.expect( "\$", timeout=60 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800447 handle = self.handle.before
448
449 return handle
450 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800451 main.log.info( "NO HANDLE" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800452 return main.FALSE
453
pingping-lin763ee042015-05-20 17:45:30 -0700454
pingping-lin4e7b0d32015-01-27 18:06:22 -0800455 # Please use the generateRoutes plus addRoutes instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800456 def addRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700457 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800458 self.handle.sendline( "" )
459 self.handle.expect( "config-router" )
pingping-lin763ee042015-05-20 17:45:30 -0700460 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800461 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700462 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800463 main.log.info( "Adding Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800464 j = 0
465 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700466 while numRoutes > 255:
467 numRoutes = numRoutes - 255
468 j = j + 1
469 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800470 routesAdded = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700471 if numRoutes > 255:
472 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800473 for m in range( 1, j + 1 ):
474 for n in range( 1, numRoutes + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800475 network = str( net ) + "." + str( m ) + "." + str( n ) \
476 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700477 routeCmd = "network " + network
478 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800479 self.handle.sendline( routeCmd )
480 self.handle.expect( "bgpd" )
pingping-lin763ee042015-05-20 17:45:30 -0700481 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800482 main.log.warn( "failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800483 self.disconnect()
484 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800485 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800486 routesAdded = routesAdded + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800487 for d in range( j + 1, j + 2 ):
488 for e in range( 1, k + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800489 network = str( net ) + "." + str( d ) + "." + str( e ) \
490 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700491 routeCmd = "network " + network
492 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800493 self.handle.sendline( routeCmd )
494 self.handle.expect( "bgpd" )
pingping-lin763ee042015-05-20 17:45:30 -0700495 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800496 main.log.warn( "failed to add route" )
pingping-lin763ee042015-05-20 17:45:30 -0700497 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800498 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800499 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800500 routesAdded = routesAdded + 1
501 if routesAdded == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700502 return main.TRUE
503 return main.FALSE
pingping-lin0904ad02015-01-30 15:18:14 -0800504
pingping-lin4e7b0d32015-01-27 18:06:22 -0800505 # Please use deleteRoutes method instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 def delRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700507 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800508 self.handle.sendline( "" )
509 self.handle.expect( "config-router" )
pingping-lin763ee042015-05-20 17:45:30 -0700510 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800511 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700512 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800513 main.log.info( "Deleting Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800514 j = 0
515 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700516 while numRoutes > 255:
517 numRoutes = numRoutes - 255
518 j = j + 1
519 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 routesDeleted = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700521 if numRoutes > 255:
522 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800523 for m in range( 1, j + 1 ):
524 for n in range( 1, numRoutes + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800525 network = str( net ) + "." + str( m ) + "." + str( n ) \
526 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700527 routeCmd = "no network " + network
528 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800529 self.handle.sendline( routeCmd )
530 self.handle.expect( "bgpd" )
pingping-lin763ee042015-05-20 17:45:30 -0700531 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800532 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700533 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800534 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800535 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 routesDeleted = routesDeleted + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800537 for d in range( j + 1, j + 2 ):
538 for e in range( 1, k + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800539 network = str( net ) + "." + str( d ) + "." + str( e ) \
540 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700541 routeCmd = "no network " + network
542 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800543 self.handle.sendline( routeCmd )
544 self.handle.expect( "bgpd" )
pingping-lin763ee042015-05-20 17:45:30 -0700545 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800546 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700547 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800548 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800549 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800550 routesDeleted = routesDeleted + 1
551 if routesDeleted == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700552 return main.TRUE
553 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800554
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 def checkRoutes( self, brand, ip, user, pw ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800556 def pronto( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700557 print "Connecting to Pronto switch"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800558 child = pexpect.spawn( "telnet " + ip )
559 i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700560 if i == 0:
pingping-linc1c696e2015-01-27 13:46:44 -0800561 print "user_name and password required. Passing login info."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800562 child.sendline( user )
563 child.expect( "Password:" )
564 child.sendline( passwd )
565 child.expect( "CLI#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700566 print "Logged in, getting flowtable."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800567 child.sendline( "flowtable brief" )
568 for t in range( 9 ):
timlindbergef8d55d2013-09-27 12:50:13 -0700569 t2 = 9 - t
kelvin-onlabbbe46482015-01-16 10:44:28 -0800570 print "\r" + str( t2 )
571 sys.stdout.write( "\033[F" )
572 time.sleep( 1 )
timlindbergef8d55d2013-09-27 12:50:13 -0700573 print "Scanning flowtable"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800574 child.expect( "Flow table show" )
timlindbergef8d55d2013-09-27 12:50:13 -0700575 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800576 while True:
pingping-lin0904ad02015-01-30 15:18:14 -0800577 i = child.expect( [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
pingping-lin4e7b0d32015-01-27 18:06:22 -0800578 'CLI#', pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700579 if i == 0:
580 count = count + 1
581 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800582 print "Pronto flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700583 break
584 else:
585 break
kelvin-onlabbbe46482015-01-16 10:44:28 -0800586
587 def cisco( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700588 print "Establishing Cisco switch connection"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800589 child = pexpect.spawn( "ssh " + user + "@" + ip )
590 i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700591 if i == 0:
592 print "Password required. Passing now."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800593 child.sendline( passwd )
594 child.expect( "#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700595 print "Logged in. Retrieving flow table then counting flows."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800596 child.sendline( "show openflow switch all flows all" )
597 child.expect( "Logical Openflow Switch" )
timlindbergef8d55d2013-09-27 12:50:13 -0700598 print "Flow table retrieved. Counting flows"
599 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800600 while True:
601 i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700602 if i == 0:
603 count = count + 1
604 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800605 print "Cisco flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700606 break
607 else:
608 break
609 if brand == "pronto" or brand == "PRONTO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800610 pronto( ip, user, passwd )
pingping-linc6b86fa2014-12-01 16:18:10 -0800611 # elif brand == "cisco" or brand == "CISCO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800612 # cisco( ip,user,passwd )
613
pingping-lin763ee042015-05-20 17:45:30 -0700614 def disable_bgp_peer( self, peer, peer_as ):
615 main.log.info( "I am in disconnect_peer_session method!" )
616
617 try:
618 self.handle.sendline( "" )
619 # self.handle.expect( "config-router" )
620 self.handle.expect( "config-router", timeout=5 )
621 except Exception:
622 main.log.warn( "Probably not in config-router mode!" )
623 self.disconnect()
624 main.log.info( "Start to disable peer" )
625
626 cmd = "no neighbor " + peer + " remote-as " + peer_as
627 try:
628 self.handle.sendline( cmd )
629 self.handle.expect( "bgpd", timeout=5 )
630 except Exception:
631 main.log.warn( "Failed to disable peer" )
632 self.disconnect()
633
634 def enable_bgp_peer( self, peer, peer_as ):
635 main.log.info( "I am in enable_bgp_peer method!" )
636
637 try:
638 self.handle.sendline( "" )
639 # self.handle.expect( "config-router" )
640 self.handle.expect( "config-router", timeout=5 )
641 except Exception:
642 main.log.warn( "Probably not in config-router mode!" )
643 self.disconnect()
644 main.log.info( "Start to disable peer" )
645
646 cmd = "neighbor " + peer + " remote-as " + peer_as
647 try:
648 self.handle.sendline( cmd )
649 self.handle.expect( "bgpd", timeout=5 )
650 except Exception:
651 main.log.warn( "Failed to enable peer" )
652 self.disconnect()
653
kelvin-onlabbbe46482015-01-16 10:44:28 -0800654 def disconnect( self ):
655 """
656 Called when Test is complete to disconnect the Quagga handle.
657 """
timlindbergef8d55d2013-09-27 12:50:13 -0700658 response = ''
659 try:
660 self.handle.close()
pingping-lin763ee042015-05-20 17:45:30 -0700661 except Exception:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800662 main.log.error( "Connection failed to the host" )
timlindbergef8d55d2013-09-27 12:50:13 -0700663 response = main.FALSE
664 return response
pingping-linc1c696e2015-01-27 13:46:44 -0800665