blob: 87de64d7b36d3739a3639367df131507ce9a8de3 [file] [log] [blame]
timlindbergef8d55d2013-09-27 12:50:13 -07001#!/usr/bin/env python
2
3import time
4import pexpect
kelvin-onlabbbe46482015-01-16 10:44:28 -08005import struct
6import fcntl
7import os
8import sys
9import signal
timlindbergef8d55d2013-09-27 12:50:13 -070010import sys
11import re
12import json
kelvin-onlabbbe46482015-01-16 10:44:28 -080013sys.path.append( "../" )
timlindbergef8d55d2013-09-27 12:50:13 -070014from drivers.common.clidriver import CLI
15
timlindbergef8d55d2013-09-27 12:50:13 -070016
kelvin-onlabbbe46482015-01-16 10:44:28 -080017class QuaggaCliDriver( CLI ):
18
19 def __init__( self ):
20 super( CLI, self ).__init__()
timlindbergef8d55d2013-09-27 12:50:13 -070021
pingping-linc6b86fa2014-12-01 16:18:10 -080022 # TODO: simplify this method
kelvin-onlabbbe46482015-01-16 10:44:28 -080023 def connect( self, **connectargs ):
timlindbergef8d55d2013-09-27 12:50:13 -070024 for key in connectargs:
kelvin-onlabbbe46482015-01-16 10:44:28 -080025 vars( self )[ key ] = connectargs[ key ]
pingping-linc6b86fa2014-12-01 16:18:10 -080026
kelvin-onlabbbe46482015-01-16 10:44:28 -080027 self.name = self.options[ 'name' ]
28 # self.handle = super( QuaggaCliDriver,self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080029 # user_name=self.user_name, ip_address=self.ip_address,port=self.port,
kelvin-onlabbbe46482015-01-16 10:44:28 -080030 # pwd=self.pwd )
pingping-lin4e7b0d32015-01-27 18:06:22 -080031 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080032 user_name=self.user_name,
33 ip_address="1.1.1.1",
34 port=self.port,
35 pwd=self.pwd )
pingping-lina600d9b2015-01-30 13:57:26 -080036 #main.log.info( "connect parameters:" + str( self.user_name ) + ";"
37 # + str( self.ip_address ) + ";" + str( self.port )
38 # + ";" + str(self.pwd ) )
timlindbergef8d55d2013-09-27 12:50:13 -070039
pingping-linc6b86fa2014-12-01 16:18:10 -080040 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080041 # self.handle.expect( "",timeout=10 )
42 # self.handle.expect( "\$",timeout=10 )
43 self.handle.sendline( "telnet localhost 2605" )
44 # self.handle.expect( "Password:", timeout=5 )
45 self.handle.expect( "Password:" )
46 self.handle.sendline( "hello" )
47 # self.handle.expect( "bgpd", timeout=5 )
48 self.handle.expect( "bgpd" )
49 self.handle.sendline( "enable" )
50 # self.handle.expect( "bgpd#", timeout=5 )
51 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -070052 return self.handle
kelvin-onlabbbe46482015-01-16 10:44:28 -080053 else:
54 main.log.info( "NO HANDLE" )
timlindbergef8d55d2013-09-27 12:50:13 -070055 return main.FALSE
56
pingping-linc1c696e2015-01-27 13:46:44 -080057 def loginQuagga( self, ip_address ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080058 self.name = self.options[ 'name' ]
59 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -080060 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -080061 port=self.port, pwd=self.pwd )
pingping-linc1c696e2015-01-27 13:46:44 -080062 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
pingping-lin4e7b0d32015-01-27 18:06:22 -080063 + str( self.ip_address ) + ";" + str( self.port )
64 + ";" + str( self.pwd ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080065
66 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -080067 # self.handle.expect( "" )
68 # self.handle.expect( "\$" )
69 self.handle.sendline( "telnet localhost 2605" )
70 # self.handle.expect( "Password:", timeout=5 )
71 self.handle.expect( "Password:" )
72 self.handle.sendline( "hello" )
73 # self.handle.expect( "bgpd", timeout=5 )
74 self.handle.expect( "bgpd" )
75 self.handle.sendline( "enable" )
76 # self.handle.expect( "bgpd#", timeout=5 )
77 self.handle.expect( "bgpd#" )
pingping-linc1c696e2015-01-27 13:46:44 -080078 main.log.info( "I am in quagga on host " + str( ip_address ) )
pingping-lin8b306ac2014-11-17 18:13:51 -080079
80 return self.handle
81 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -080082 main.log.info( "NO HANDLE" )
pingping-lin8b306ac2014-11-17 18:13:51 -080083 return main.FALSE
84
kelvin-onlabd3b64892015-01-20 13:26:24 -080085 def enterConfig( self, asn ):
kelvin-onlabbbe46482015-01-16 10:44:28 -080086 main.log.info( "I am in enter_config method!" )
timlindbergef8d55d2013-09-27 12:50:13 -070087 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -080088 self.handle.sendline( "" )
89 self.handle.expect( "bgpd#" )
timlindbergef8d55d2013-09-27 12:50:13 -070090 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -080091 main.log.warn( "Probably not currently in enable mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -070092 self.disconnect()
93 return main.FALSE
kelvin-onlabbbe46482015-01-16 10:44:28 -080094 self.handle.sendline( "configure terminal" )
95 self.handle.expect( "config", timeout=5 )
96 routerAS = "router bgp " + str( asn )
timlindbergef8d55d2013-09-27 12:50:13 -070097 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -080098 self.handle.sendline( routerAS )
99 self.handle.expect( "config-router", timeout=5 )
timlindbergef8d55d2013-09-27 12:50:13 -0700100 return main.TRUE
101 except:
102 return main.FALSE
pingping-lin8b306ac2014-11-17 18:13:51 -0800103
kelvin-onlabd3b64892015-01-20 13:26:24 -0800104 def generatePrefixes( self, net, numRoutes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800105 main.log.info( "I am in generate_prefixes method!" )
pingping-lin6f6332e2014-11-19 19:13:58 -0800106
pingping-lin4e7b0d32015-01-27 18:06:22 -0800107 # each IP prefix is composed by "net" + "." + m + "." + n + "." + x
pingping-lin8b306ac2014-11-17 18:13:51 -0800108 # the length of each IP prefix is 24
109 routes = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800110 routesGen = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800111 m = numRoutes / 256
112 n = numRoutes % 256
113
kelvin-onlabbbe46482015-01-16 10:44:28 -0800114 for i in range( 0, m ):
115 for j in range( 0, 256 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800116 network = str( net ) + "." + str( i ) + "." + str( j ) \
117 + ".0/24"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800118 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800119 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800120
kelvin-onlabbbe46482015-01-16 10:44:28 -0800121 for j in range( 0, n ):
122 network = str( net ) + "." + str( m ) + "." + str( j ) + ".0/24"
123 routes.append( network )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800124 routesGen = routesGen + 1
pingping-lin8b306ac2014-11-17 18:13:51 -0800125
kelvin-onlabd3b64892015-01-20 13:26:24 -0800126 if routesGen == numRoutes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800127 main.log.info( "Successfully generated " + str( numRoutes )
128 + " prefixes!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800129 return routes
130 return main.FALSE
pingping-lin6f6332e2014-11-19 19:13:58 -0800131
kelvin-onlabbbe46482015-01-16 10:44:28 -0800132 # This method generates a multiple to single point intent(
133 # MultiPointToSinglePointIntent ) for a given route
pingping-lin4e7b0d32015-01-27 18:06:22 -0800134 def generateExpectedSingleRouteIntent( self, prefix, nextHop, nextHopMac,
135 sdnipData ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800136
pingping-linc1c696e2015-01-27 13:46:44 -0800137 ingresses = []
pingping-lin6f6332e2014-11-19 19:13:58 -0800138 egress = ""
kelvin-onlabd3b64892015-01-20 13:26:24 -0800139 for peer in sdnipData[ 'bgpPeers' ]:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800140 if peer[ 'ipAddress' ] == nextHop:
pingping-linc1c696e2015-01-27 13:46:44 -0800141 egress = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800142 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
143 + str( peer[ 'attachmentPort' ] )
pingping-linc1c696e2015-01-27 13:46:44 -0800144 for peer in sdnipData[ 'bgpPeers' ]:
145 if not peer[ 'ipAddress' ] == nextHop:
146 ingress = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800147 peer[ 'attachmentDpid' ] ).replace( ":", "" ) + ":" \
148 + str( peer[ 'attachmentPort' ] )
pingping-linc1c696e2015-01-27 13:46:44 -0800149 if not ingress == egress and ingress not in ingresses:
150 ingresses.append( ingress )
151 # ingresses.append( "of:" + str( peer[ 'attachmentDpid' ]
152 # ).replace( ":", "" ) + ":" + str( peer[ 'attachmentPort'
153 # ] ) )
pingping-lin6f6332e2014-11-19 19:13:58 -0800154
pingping-linc6b86fa2014-12-01 16:18:10 -0800155 selector = "ETH_TYPE{ethType=800},IPV4_DST{ip=" + prefix + "}"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800156 treatment = "[ETH_DST{mac=" + str( nextHopMac ) + "}]"
pingping-lin6f6332e2014-11-19 19:13:58 -0800157
pingping-lin4e7b0d32015-01-27 18:06:22 -0800158 intent = egress + "/" + str( sorted( ingresses ) ) + "/" + \
159 selector + "/" + treatment
pingping-lin6f6332e2014-11-19 19:13:58 -0800160 return intent
161
pingping-lin4e7b0d32015-01-27 18:06:22 -0800162 def generateExpectedOnePeerRouteIntents( self, prefixes, nextHop,
163 nextHopMac, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800164 intents = []
kelvin-onlabd3b64892015-01-20 13:26:24 -0800165 sdnipJsonFile = open( sdnipJsonFilePath ).read()
pingping-lin6f6332e2014-11-19 19:13:58 -0800166
kelvin-onlabd3b64892015-01-20 13:26:24 -0800167 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800168
169 for prefix in prefixes:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800170 intents.append(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800171 self.generateExpectedSingleRouteIntent(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800172 prefix, nextHop, nextHopMac, sdnipData ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800173 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800174
175 # TODO
176 # This method generates all expected route intents for all BGP peers
kelvin-onlabd3b64892015-01-20 13:26:24 -0800177 def generateExpectedRouteIntents( self ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800178 intents = []
179 return intents
180
181 # This method extracts all actual routes from ONOS CLI
pingping-linb2a86582015-02-02 16:18:59 -0800182 def extractActualRoutesOneDotZero( self, getRoutesResult ):
kelvin-onlabd3b64892015-01-20 13:26:24 -0800183 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-linb2a86582015-02-02 16:18:59 -0800193
194 def extractActualRoutesMaster( self, getRoutesResult ):
pingping-lina600d9b2015-01-30 13:57:26 -0800195 routesJsonObj = json.loads( getRoutesResult )
196
197 allRoutesActual = []
198 for route in routesJsonObj['routes4']:
199 if route[ 'prefix' ] == '172.16.10.0/24':
200 continue
201 allRoutesActual.append(
202 route[ 'prefix' ] + "/" + route[ 'nextHop' ] )
203
204 return sorted( allRoutesActual )
pingping-lin6f6332e2014-11-19 19:13:58 -0800205
206 # This method extracts all actual route intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800207 def extractActualRouteIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800208 intents = []
209 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800210 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
211 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800212
kelvin-onlabd3b64892015-01-20 13:26:24 -0800213 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800214 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800215 continue
pingping-lin4e7b0d32015-01-27 18:06:22 -0800216 if intent[ 'type' ] == "MultiPointToSinglePointIntent" \
217 and intent[ 'state' ] == 'INSTALLED':
218 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" \
219 + str( intent[ 'egress' ][ 'port' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800220 ingress = []
kelvin-onlabbbe46482015-01-16 10:44:28 -0800221 for attachmentPoint in intent[ 'ingress' ]:
pingping-linc1c696e2015-01-27 13:46:44 -0800222 ingress.append(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800223 str( attachmentPoint[ 'device' ] ) + ":"
224 + str( attachmentPoint[ 'port' ] ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800225
kelvin-onlabbbe46482015-01-16 10:44:28 -0800226 selector = intent[ 'selector' ].replace(
227 "[", "" ).replace( "]", "" ).replace( " ", "" )
228 if str( selector ).startswith( "IPV4" ):
229 str1, str2 = str( selector ).split( "," )
pingping-linc6b86fa2014-12-01 16:18:10 -0800230 selector = str2 + "," + str1
231
pingping-lin4e7b0d32015-01-27 18:06:22 -0800232 intent = egress + "/" + str( sorted( ingress ) ) + "/" + \
233 selector + "/" + intent[ 'treatment' ]
kelvin-onlabbbe46482015-01-16 10:44:28 -0800234 intents.append( intent )
235 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800236
237 # This method extracts all actual BGP intents from ONOS CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 def extractActualBgpIntents( self, getIntentsResult ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800239 intents = []
240 # TODO: delete the line below when change to Mininet demo script
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 # getIntentsResult=open( "../tests/SdnIpTest/intents.json" ).read()
242 intentsJsonObj = json.loads( getIntentsResult )
pingping-lin6f6332e2014-11-19 19:13:58 -0800243
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 for intent in intentsJsonObj:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800245 if intent[ 'appId' ] != "org.onosproject.sdnip":
pingping-lin6f6332e2014-11-19 19:13:58 -0800246 continue
pingping-lin4e7b0d32015-01-27 18:06:22 -0800247 if intent[ 'type' ] == "PointToPointIntent" \
248 and "protocol=6" in str( intent[ 'selector' ] ):
249 ingress = str( intent[ 'ingress' ][ 'device' ] ) + ":" \
250 + str( intent[ 'ingress' ][ 'port' ] )
251 egress = str( intent[ 'egress' ][ 'device' ] ) + ":" + \
252 str( intent[ 'egress' ][ 'port' ] )
253 selector = str( intent[ 'selector' ] ).replace( " ", "" )\
254 .replace( "[", "" ).replace( "]", "" ).split( "," )
255 intent = ingress + "/" + egress + "/" + \
256 str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800257 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800258
kelvin-onlabbbe46482015-01-16 10:44:28 -0800259 return sorted( intents )
pingping-lin6f6332e2014-11-19 19:13:58 -0800260
kelvin-onlabbbe46482015-01-16 10:44:28 -0800261 # This method generates a single point to single point intent(
262 # PointToPointIntent ) for BGP path
kelvin-onlabd3b64892015-01-20 13:26:24 -0800263 def generateExpectedBgpIntents( self, sdnipJsonFilePath ):
pingping-lin6f6332e2014-11-19 19:13:58 -0800264 from operator import eq
265
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 sdnipJsonFile = open( sdnipJsonFilePath ).read()
267 sdnipData = json.loads( sdnipJsonFile )
pingping-lin6f6332e2014-11-19 19:13:58 -0800268
269 intents = []
pingping-linc6b86fa2014-12-01 16:18:10 -0800270 bgpPeerAttachmentPoint = ""
kelvin-onlabbbe46482015-01-16 10:44:28 -0800271 bgpSpeakerAttachmentPoint = "of:" + str(
pingping-lin4e7b0d32015-01-27 18:06:22 -0800272 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] )\
273 .replace( ":", "" ) + ":" \
274 + str( sdnipData[ 'bgpSpeakers' ][ 0 ][ 'attachmentPort' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 for peer in sdnipData[ 'bgpPeers' ]:
pingping-lin4e7b0d32015-01-27 18:06:22 -0800276 bgpPeerAttachmentPoint = "of:" \
277 + str( peer[ 'attachmentDpid' ] ).replace( ":", "" ) \
278 + ":" + str( peer[ 'attachmentPort' ] )
pingping-lin6f6332e2014-11-19 19:13:58 -0800279 # find out the BGP speaker IP address for this BGP peer
pingping-linc6b86fa2014-12-01 16:18:10 -0800280 bgpSpeakerIpAddress = ""
pingping-lin4e7b0d32015-01-27 18:06:22 -0800281 for interfaceAddress in \
282 sdnipData[ 'bgpSpeakers' ][ 0 ][ 'interfaceAddresses' ]:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 # if eq( interfaceAddress[ 'interfaceDpid' ],sdnipData[
kelvin-onlabbbe46482015-01-16 10:44:28 -0800284 # 'bgpSpeakers' ][ 0 ][ 'attachmentDpid' ] ) and eq(
pingping-linc1c696e2015-01-27 13:46:44 -0800285 # interfaceAddress[ 'interfacePort' ], sdnipData[ 'bgpSpeakers'
286 # ][ 0 ][ 'attachmentPort' ] ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800287 if eq( interfaceAddress[ 'interfaceDpid' ],
288 peer[ 'attachmentDpid' ] ) \
289 and eq( interfaceAddress[ 'interfacePort' ],
290 peer[ 'attachmentPort' ] ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800291 bgpSpeakerIpAddress = interfaceAddress[ 'ipAddress' ]
pingping-lin6f6332e2014-11-19 19:13:58 -0800292 break
293 else:
294 continue
295
kelvin-onlabbbe46482015-01-16 10:44:28 -0800296 # from bgpSpeakerAttachmentPoint to bgpPeerAttachmentPoint
297 # direction
pingping-lin4e7b0d32015-01-27 18:06:22 -0800298 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
299 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
300 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
301 TCP_DST{tcpPort=179}"
302 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
303 .replace( "]", "" ).split( "," )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800304 intent = bgpSpeakerAttachmentPoint + "/" + \
305 bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
306 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800307
pingping-lin4e7b0d32015-01-27 18:06:22 -0800308 selectorStr = "IPV4_SRC{ip=" + bgpSpeakerIpAddress + "/32}," \
309 + "IPV4_DST{ip=" + peer[ 'ipAddress' ] + "/32}," \
310 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
311 TCP_SRC{tcpPort=179}"
312 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
313 .replace( "]", "" ).split( "," )
314 intent = bgpSpeakerAttachmentPoint + "/" \
315 + bgpPeerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800316 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800317
kelvin-onlabbbe46482015-01-16 10:44:28 -0800318 # from bgpPeerAttachmentPoint to bgpSpeakerAttachmentPoint
319 # direction
pingping-lin4e7b0d32015-01-27 18:06:22 -0800320 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
321 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
322 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
323 TCP_DST{tcpPort=179}"
324 selector = selectorStr.replace( " ", "" ).replace("[", "" )\
325 .replace( "]", "" ).split( "," )
326 intent = bgpPeerAttachmentPoint + "/" \
327 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800328 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800329
pingping-lin4e7b0d32015-01-27 18:06:22 -0800330 selectorStr = "IPV4_SRC{ip=" + peer[ 'ipAddress' ] + "/32}," \
331 + "IPV4_DST{ip=" + bgpSpeakerIpAddress + "/32}," \
332 + "IP_PROTO{protocol=6}, ETH_TYPE{ethType=800}, \
333 TCP_SRC{tcpPort=179}"
334 selector = selectorStr.replace( " ", "" ).replace( "[", "" )\
335 .replace( "]", "" ).split( "," )
336 intent = bgpPeerAttachmentPoint + "/" \
337 + bgpSpeakerAttachmentPoint + "/" + str( sorted( selector ) )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800338 intents.append( intent )
pingping-lin6f6332e2014-11-19 19:13:58 -0800339
kelvin-onlabbbe46482015-01-16 10:44:28 -0800340 return sorted( intents )
pingping-linc6b86fa2014-12-01 16:18:10 -0800341
kelvin-onlabd3b64892015-01-20 13:26:24 -0800342 def addRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800343 main.log.info( "I am in add_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800344
kelvin-onlabd3b64892015-01-20 13:26:24 -0800345 routesAdded = 0
pingping-lin8b306ac2014-11-17 18:13:51 -0800346 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800347 self.handle.sendline( "" )
348 # self.handle.expect( "config-router" )
349 self.handle.expect( "config-router", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800350 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800351 main.log.warn( "Probably not in config-router mode!" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800352 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800353 main.log.info( "Start to add routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800354
kelvin-onlabbbe46482015-01-16 10:44:28 -0800355 for i in range( 0, len( routes ) ):
356 routeCmd = "network " + routes[ i ]
pingping-lin8b306ac2014-11-17 18:13:51 -0800357 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800358 self.handle.sendline( routeCmd )
359 self.handle.expect( "bgpd", timeout=5 )
pingping-lin8b306ac2014-11-17 18:13:51 -0800360 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800361 main.log.warn( "Failed to add route" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800362 self.disconnect()
pingping-linc1c696e2015-01-27 13:46:44 -0800363 # waitTimer = 1.00 / routeRate
364 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800365 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800366 main.log.info( "Finished adding routes" )
pingping-lin8b306ac2014-11-17 18:13:51 -0800367 return main.TRUE
368 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800369
kelvin-onlabd3b64892015-01-20 13:26:24 -0800370 def deleteRoutes( self, routes, routeRate ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800371 main.log.info( "I am in delete_routes method!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800372
kelvin-onlabd3b64892015-01-20 13:26:24 -0800373 routesAdded = 0
pingping-linc6b86fa2014-12-01 16:18:10 -0800374 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800375 self.handle.sendline( "" )
376 # self.handle.expect( "config-router" )
377 self.handle.expect( "config-router", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800378 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800379 main.log.warn( "Probably not in config-router mode!" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800380 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800381 main.log.info( "Start to delete routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800382
kelvin-onlabbbe46482015-01-16 10:44:28 -0800383 for i in range( 0, len( routes ) ):
384 routeCmd = "no network " + routes[ i ]
pingping-linc6b86fa2014-12-01 16:18:10 -0800385 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800386 self.handle.sendline( routeCmd )
387 self.handle.expect( "bgpd", timeout=5 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800388 except:
pingping-lin4e7b0d32015-01-27 18:06:22 -0800389 main.log.warn( "Failed to delete route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800390 self.disconnect()
pingping-linc1c696e2015-01-27 13:46:44 -0800391 # waitTimer = 1.00 / routeRate
392 # time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800393 if routesAdded == len( routes ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800394 main.log.info( "Finished deleting routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800395 return main.TRUE
396 return main.FALSE
397
pingping-linc1c696e2015-01-27 13:46:44 -0800398 def pingTest( self, ip_address, pingTestFile, pingTestResultFile ):
399 main.log.info( "Start the ping test on host:" + str( ip_address ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800400
kelvin-onlabbbe46482015-01-16 10:44:28 -0800401 self.name = self.options[ 'name' ]
402 self.handle = super( QuaggaCliDriver, self ).connect(
pingping-linc1c696e2015-01-27 13:46:44 -0800403 user_name=self.user_name, ip_address=ip_address,
kelvin-onlabbbe46482015-01-16 10:44:28 -0800404 port=self.port, pwd=self.pwd )
pingping-linc1c696e2015-01-27 13:46:44 -0800405 main.log.info( "connect parameters:" + str( self.user_name ) + ";"
pingping-lin4e7b0d32015-01-27 18:06:22 -0800406 + str( self.ip_address ) + ";" + str( self.port )
407 + ";" + str( self.pwd ) )
pingping-linc6b86fa2014-12-01 16:18:10 -0800408
409 if self.handle:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800410 # self.handle.expect( "" )
411 # self.handle.expect( "\$" )
pingping-linc1c696e2015-01-27 13:46:44 -0800412 main.log.info( "I in host " + str( ip_address ) )
413 main.log.info( pingTestFile + " > " + pingTestResultFile + " &" )
kelvin-onlabbbe46482015-01-16 10:44:28 -0800414 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800415 pingTestFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800416 " > " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800417 pingTestResultFile +
kelvin-onlabbbe46482015-01-16 10:44:28 -0800418 " &" )
419 self.handle.expect( "\$", timeout=60 )
pingping-linc6b86fa2014-12-01 16:18:10 -0800420 handle = self.handle.before
421
422 return handle
423 else:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800424 main.log.info( "NO HANDLE" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800425 return main.FALSE
426
pingping-lin4e7b0d32015-01-27 18:06:22 -0800427 # Please use the generateRoutes plus addRoutes instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800428 def addRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700429 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800430 self.handle.sendline( "" )
431 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700432 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800433 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700434 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800435 main.log.info( "Adding Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800436 j = 0
437 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700438 while numRoutes > 255:
439 numRoutes = numRoutes - 255
440 j = j + 1
441 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800442 routesAdded = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700443 if numRoutes > 255:
444 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800445 for m in range( 1, j + 1 ):
446 for n in range( 1, numRoutes + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800447 network = str( net ) + "." + str( m ) + "." + str( n ) \
448 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700449 routeCmd = "network " + network
450 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800451 self.handle.sendline( routeCmd )
452 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700453 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800454 main.log.warn( "failed to add route" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800455 self.disconnect()
456 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800457 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800458 routesAdded = routesAdded + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800459 for d in range( j + 1, j + 2 ):
460 for e in range( 1, k + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800461 network = str( net ) + "." + str( d ) + "." + str( e ) \
462 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700463 routeCmd = "network " + network
464 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800465 self.handle.sendline( routeCmd )
466 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700467 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800468 main.log.warn( "failed to add route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700469 self.disconnect
pingping-linc6b86fa2014-12-01 16:18:10 -0800470 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800471 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472 routesAdded = routesAdded + 1
473 if routesAdded == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700474 return main.TRUE
475 return main.FALSE
pingping-lin0904ad02015-01-30 15:18:14 -0800476
pingping-lin4e7b0d32015-01-27 18:06:22 -0800477 # Please use deleteRoutes method instead of this one!
kelvin-onlabd3b64892015-01-20 13:26:24 -0800478 def delRoute( self, net, numRoutes, routeRate ):
timlindbergef8d55d2013-09-27 12:50:13 -0700479 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800480 self.handle.sendline( "" )
481 self.handle.expect( "config-router" )
timlindbergef8d55d2013-09-27 12:50:13 -0700482 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800483 main.log.warn( "Probably not in config-router mode!" )
timlindbergef8d55d2013-09-27 12:50:13 -0700484 self.disconnect()
kelvin-onlabbbe46482015-01-16 10:44:28 -0800485 main.log.info( "Deleting Routes" )
pingping-linc6b86fa2014-12-01 16:18:10 -0800486 j = 0
487 k = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700488 while numRoutes > 255:
489 numRoutes = numRoutes - 255
490 j = j + 1
491 k = numRoutes % 254
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 routesDeleted = 0
timlindbergef8d55d2013-09-27 12:50:13 -0700493 if numRoutes > 255:
494 numRoutes = 255
kelvin-onlabbbe46482015-01-16 10:44:28 -0800495 for m in range( 1, j + 1 ):
496 for n in range( 1, numRoutes + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800497 network = str( net ) + "." + str( m ) + "." + str( n ) \
498 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700499 routeCmd = "no network " + network
500 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800501 self.handle.sendline( routeCmd )
502 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700503 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800504 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700505 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800506 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800507 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800508 routesDeleted = routesDeleted + 1
kelvin-onlabbbe46482015-01-16 10:44:28 -0800509 for d in range( j + 1, j + 2 ):
510 for e in range( 1, k + 1 ):
pingping-lin4e7b0d32015-01-27 18:06:22 -0800511 network = str( net ) + "." + str( d ) + "." + str( e ) \
512 + ".0/24"
timlindbergef8d55d2013-09-27 12:50:13 -0700513 routeCmd = "no network " + network
514 try:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800515 self.handle.sendline( routeCmd )
516 self.handle.expect( "bgpd" )
timlindbergef8d55d2013-09-27 12:50:13 -0700517 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800518 main.log.warn( "Failed to delete route" )
timlindbergef8d55d2013-09-27 12:50:13 -0700519 self.disconnect()
pingping-linc6b86fa2014-12-01 16:18:10 -0800520 waitTimer = 1.00 / routeRate
kelvin-onlabbbe46482015-01-16 10:44:28 -0800521 time.sleep( waitTimer )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 routesDeleted = routesDeleted + 1
523 if routesDeleted == numRoutes:
timlindbergef8d55d2013-09-27 12:50:13 -0700524 return main.TRUE
525 return main.FALSE
pingping-linc6b86fa2014-12-01 16:18:10 -0800526
kelvin-onlabd3b64892015-01-20 13:26:24 -0800527 def checkRoutes( self, brand, ip, user, pw ):
kelvin-onlabbbe46482015-01-16 10:44:28 -0800528 def pronto( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700529 print "Connecting to Pronto switch"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800530 child = pexpect.spawn( "telnet " + ip )
531 i = child.expect( [ "login:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700532 if i == 0:
pingping-linc1c696e2015-01-27 13:46:44 -0800533 print "user_name and password required. Passing login info."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800534 child.sendline( user )
535 child.expect( "Password:" )
536 child.sendline( passwd )
537 child.expect( "CLI#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700538 print "Logged in, getting flowtable."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800539 child.sendline( "flowtable brief" )
540 for t in range( 9 ):
timlindbergef8d55d2013-09-27 12:50:13 -0700541 t2 = 9 - t
kelvin-onlabbbe46482015-01-16 10:44:28 -0800542 print "\r" + str( t2 )
543 sys.stdout.write( "\033[F" )
544 time.sleep( 1 )
timlindbergef8d55d2013-09-27 12:50:13 -0700545 print "Scanning flowtable"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800546 child.expect( "Flow table show" )
timlindbergef8d55d2013-09-27 12:50:13 -0700547 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800548 while True:
pingping-lin0904ad02015-01-30 15:18:14 -0800549 i = child.expect( [ '17\d\.\d{1,3}\.\d{1,3}\.\d{1,3}',
pingping-lin4e7b0d32015-01-27 18:06:22 -0800550 'CLI#', pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700551 if i == 0:
552 count = count + 1
553 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800554 print "Pronto flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700555 break
556 else:
557 break
kelvin-onlabbbe46482015-01-16 10:44:28 -0800558
559 def cisco( ip, user, passwd ):
timlindbergef8d55d2013-09-27 12:50:13 -0700560 print "Establishing Cisco switch connection"
kelvin-onlabbbe46482015-01-16 10:44:28 -0800561 child = pexpect.spawn( "ssh " + user + "@" + ip )
562 i = child.expect( [ "Password:", "CLI#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700563 if i == 0:
564 print "Password required. Passing now."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800565 child.sendline( passwd )
566 child.expect( "#" )
timlindbergef8d55d2013-09-27 12:50:13 -0700567 print "Logged in. Retrieving flow table then counting flows."
kelvin-onlabbbe46482015-01-16 10:44:28 -0800568 child.sendline( "show openflow switch all flows all" )
569 child.expect( "Logical Openflow Switch" )
timlindbergef8d55d2013-09-27 12:50:13 -0700570 print "Flow table retrieved. Counting flows"
571 count = 0
kelvin-onlabbbe46482015-01-16 10:44:28 -0800572 while True:
573 i = child.expect( [ "nw_src=17", "#", pexpect.TIMEOUT ] )
timlindbergef8d55d2013-09-27 12:50:13 -0700574 if i == 0:
575 count = count + 1
576 elif i == 1:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800577 print "Cisco flows: " + str( count ) + "\nDone\n"
timlindbergef8d55d2013-09-27 12:50:13 -0700578 break
579 else:
580 break
581 if brand == "pronto" or brand == "PRONTO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800582 pronto( ip, user, passwd )
pingping-linc6b86fa2014-12-01 16:18:10 -0800583 # elif brand == "cisco" or brand == "CISCO":
kelvin-onlabbbe46482015-01-16 10:44:28 -0800584 # cisco( ip,user,passwd )
585
586 def disconnect( self ):
587 """
588 Called when Test is complete to disconnect the Quagga handle.
589 """
timlindbergef8d55d2013-09-27 12:50:13 -0700590 response = ''
591 try:
592 self.handle.close()
593 except:
kelvin-onlabbbe46482015-01-16 10:44:28 -0800594 main.log.error( "Connection failed to the host" )
timlindbergef8d55d2013-09-27 12:50:13 -0700595 response = main.FALSE
596 return response
pingping-linc1c696e2015-01-27 13:46:44 -0800597