blob: bb17d03eda402399b1e6f329799c5210dfb8b496 [file] [log] [blame]
ChetanGaonker2099d722016-10-07 15:16:58 -07001import unittest
2from twisted.internet import defer
3from nose.tools import *
4from IGMP import *
5from ACL import ACLTest
6from DHCP import DHCPTest
7from Channels import Channels, IgmpChannel
8from subscriberDb import SubscriberDB
9import time, monotonic
10from OltConfig import OltConfig
11from OnosCtrl import OnosCtrl, get_mac
12from OnosFlowCtrl import OnosFlowCtrl
13from CordContainer import Container, Onos, Quagga
14from onosclidriver import OnosCliDriver
15from CordTestServer import CordTestServer, cord_test_onos_restart, cord_test_quagga_restart,cord_test_quagga_stop, cord_test_quagga_shell,cord_test_shell
16from portmaps import g_subscriber_port_map
17import time, monotonic
18from scapy_ssl_tls.ssl_tls import *
19from scapy_ssl_tls.ssl_tls_crypto import *
20import os
21import json
22from socket import socket
23import pexpect
24from Stats import Stats
25from scapy.all import *
26from OnosFlowCtrl import OnosFlowCtrl
27from nose.twistedtools import reactor, deferred
28import tempfile
29import threading
30from threading import current_thread
31from threadPool import ThreadPool
32import random
33import collections
34import requests
35log.setLevel('INFO')
36
37class cluster_igmp(object):
38 V_INF1 = 'veth0'
39 V_INF2 = 'veth1'
40 MGROUP1 = '239.1.2.3'
41 MGROUP2 = '239.2.2.3'
42 MINVALIDGROUP1 = '255.255.255.255'
43 MINVALIDGROUP2 = '239.255.255.255'
44 MMACGROUP1 = "01:00:5e:01:02:03"
45 MMACGROUP2 = "01:00:5e:02:02:03"
46 IGMP_DST_MAC = "01:00:5e:00:00:16"
47 IGMP_SRC_MAC = "5a:e1:ac:ec:4d:a1"
48 IP_SRC = '1.2.3.4'
49 IP_DST = '224.0.0.22'
50 NEGATIVE_TRAFFIC_STATUS = 1
51 igmp_eth = Ether(dst = IGMP_DST_MAC, type = ETH_P_IP)
52 igmp_ip = IP(dst = IP_DST)
53 IGMP_TEST_TIMEOUT = 5
54 IGMP_QUERY_TIMEOUT = 60
55 MCAST_TRAFFIC_TIMEOUT = 10
56 PORT_TX_DEFAULT = 2
57 PORT_RX_DEFAULT = 1
58 max_packets = 100
59 app = 'org.opencord.igmp'
60 olt_conf_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../setup/olt_config.json')
61 ROVER_TEST_TIMEOUT = 300 #3600*86
62 ROVER_TIMEOUT = (ROVER_TEST_TIMEOUT - 100)
63 ROVER_JOIN_TIMEOUT = 60
64
65 @classmethod
66 def setUpClass(cls):
67 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
68 cls.port_map, _ = cls.olt.olt_port_map()
69 OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
70
71 @classmethod
72 def tearDownClass(cls): pass
73
74 def setUp(self):
75 self.setUpClass()
76 self.get_igmp_intf()
77 ''' Activate the igmp app'''
78 self.onos_ctrl = OnosCtrl(self.app)
79 self.onos_ctrl.activate()
80 self.igmp_channel = IgmpChannel()
81
82 def tearDown(self): pass
83
84 def onos_load_config(self, config):
85 log.info('onos load config is %s'%config)
86 status, code = OnosCtrl.config(config)
87 if status is False:
88 log.info('JSON request returned status %d' %code)
89 assert_equal(status, True)
90 time.sleep(2)
91
92 def onos_ssm_table_load(self, groups, src_list = ['1.2.3.4'],flag = False):
93 ssm_dict = {'apps' : { 'org.onosproject.igmp' : { 'ssmTranslate' : [] } } }
94 ssm_xlate_list = ssm_dict['apps']['org.onosproject.igmp']['ssmTranslate']
95 if flag: #to maintain seperate group-source pair.
96 for i in range(len(groups)):
97 d = {}
98 d['source'] = src_list[i] or '0.0.0.0'
99 d['group'] = groups[i]
100 ssm_xlate_list.append(d)
101 else:
102 for g in groups:
103 for s in src_list:
104 d = {}
105 d['source'] = s or '0.0.0.0'
106 d['group'] = g
107 ssm_xlate_list.append(d)
108 self.onos_load_config(ssm_dict)
109 cord_port_map = {}
110 for g in groups:
111 cord_port_map[g] = (self.PORT_TX_DEFAULT, self.PORT_RX_DEFAULT)
112 self.igmp_channel.cord_port_table_load(cord_port_map)
113 time.sleep(2)
114
115 def mcast_ip_range(self,start_ip = '224.0.1.0', end_ip = '224.0.1.100'):
116 start = list(map(int, start_ip.split(".")))
117 end = list(map(int, end_ip.split(".")))
118 temp = start
119 ip_range = []
120 ip_range.append(start_ip)
121 while temp != end:
122 start[3] += 1
123 for i in (3, 2, 1):
124 if temp[i] == 255:
125 temp[i] = 0
126 temp[i-1] += 1
127 ip_range.append(".".join(map(str, temp)))
128 return ip_range
129
130 def random_mcast_ip(self,start_ip = '224.0.1.0', end_ip = '224.0.1.100'):
131 start = list(map(int, start_ip.split(".")))
132 end = list(map(int, end_ip.split(".")))
133 temp = start
134 ip_range = []
135 ip_range.append(start_ip)
136 while temp != end:
137 start[3] += 1
138 for i in (3, 2, 1):
139 if temp[i] == 255:
140 temp[i] = 0
141 temp[i-1] += 1
142 ip_range.append(".".join(map(str, temp)))
143 return random.choice(ip_range)
144
145 def source_ip_range(self,start_ip = '10.10.0.1', end_ip = '10.10.0.100'):
146 start = list(map(int, start_ip.split(".")))
147 end = list(map(int, end_ip.split(".")))
148 temp = start
149 ip_range = []
150 ip_range.append(start_ip)
151 while temp != end:
152 start[3] += 1
153 for i in (3, 2, 1):
154 if temp[i] == 255:
155 temp[i] = 0
156 temp[i-1] += 1
157 ip_range.append(".".join(map(str, temp)))
158 return ip_range
159 def iptomac(self, mcast_ip):
160 mcast_mac = '01:00:5e:'
161 octets = mcast_ip.split('.')
162 second_oct = int(octets[1]) & 127
163 third_oct = int(octets[2])
164 fourth_oct = int(octets[3])
165 mcast_mac = mcast_mac + format(second_oct,'02x') + ':' + format(third_oct, '02x') + ':' + format(fourth_oct, '02x')
166 return mcast_mac
167
168 def randomsourceip(self,start_ip = '10.10.0.1', end_ip = '10.10.0.100'):
169 start = list(map(int, start_ip.split(".")))
170 end = list(map(int, end_ip.split(".")))
171 temp = start
172 ip_range = []
173 ip_range.append(start_ip)
174 while temp != end:
175 start[3] += 1
176 for i in (3, 2, 1):
177 if temp[i] == 255:
178 temp[i] = 0
179 temp[i-1] += 1
180 ip_range.append(".".join(map(str, temp)))
181 return random.choice(ip_range)
182
183 def get_igmp_intf(self):
184 inst = os.getenv('TEST_INSTANCE', None)
185 if not inst:
186 return 'veth0'
187 inst = int(inst) + 1
188 if inst >= self.port_map['uplink']:
189 inst += 1
190 if self.port_map.has_key(inst):
191 return self.port_map[inst]
192 return 'veth0'
193
194 def igmp_verify_join(self, igmpStateList):
195 sendState, recvState = igmpStateList
196 ## check if the send is received for the groups
197 for g in sendState.groups:
198 tx_stats = sendState.group_map[g][0]
199 tx = tx_stats.count
200 assert_greater(tx, 0)
201 rx_stats = recvState.group_map[g][1]
202 rx = rx_stats.count
203 assert_greater(rx, 0)
204 log.info('Receive stats %s for group %s' %(rx_stats, g))
205
206 log.info('IGMP test verification success')
207
208 def igmp_verify_leave(self, igmpStateList, leave_groups):
209 sendState, recvState = igmpStateList[0], igmpStateList[1]
210 ## check if the send is received for the groups
211 for g in sendState.groups:
212 tx_stats = sendState.group_map[g][0]
213 rx_stats = recvState.group_map[g][1]
214 tx = tx_stats.count
215 rx = rx_stats.count
216 assert_greater(tx, 0)
217 if g not in leave_groups:
218 log.info('Received %d packets for group %s' %(rx, g))
219 for g in leave_groups:
220 rx = recvState.group_map[g][1].count
221 assert_equal(rx, 0)
222
223 log.info('IGMP test verification success')
224
225 def mcast_traffic_timer(self):
226 self.mcastTraffic.stopReceives()
227
228 def send_mcast_cb(self, send_state):
229 for g in send_state.groups:
230 send_state.update(g, tx = 1)
231 return 0
232
233 ##Runs in the context of twisted reactor thread
234 def igmp_recv(self, igmpState, iface = 'veth0'):
235 p = self.recv_socket.recv()
236 try:
237 send_time = float(p.payload.load)
238 recv_time = monotonic.monotonic()
239 except:
240 log.info('Unexpected Payload received: %s' %p.payload.load)
241 return 0
242 #log.info( 'Recv in %.6f secs' %(recv_time - send_time))
243 igmpState.update(p.dst, rx = 1, t = recv_time - send_time)
244 return 0
245
246 def send_igmp_join(self, groups, src_list = ['1.2.3.4'], record_type=IGMP_V3_GR_TYPE_INCLUDE,
247 ip_pkt = None, iface = 'veth0', ssm_load = False, delay = 1):
248 if ssm_load is True:
249 self.onos_ssm_table_load(groups, src_list)
250 igmp = IGMPv3(type = IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30,
251 gaddr=self.IP_DST)
252 for g in groups:
253 gr = IGMPv3gr(rtype= record_type, mcaddr=g)
254 gr.sources = src_list
255 igmp.grps.append(gr)
256 if ip_pkt is None:
257 ip_pkt = self.igmp_eth/self.igmp_ip
258 pkt = ip_pkt/igmp
259 IGMPv3.fixup(pkt)
260 sendp(pkt, iface=iface)
261 log.info('igmp join packet is %s'%pkt.show())
262 if delay != 0:
263 time.sleep(delay)
264
265class cluster_tls():
266 eap_app = 'org.opencord.aaa'
267 CLIENT_CERT_INVALID = '''-----BEGIN CERTIFICATE-----
268MIIEyTCCA7GgAwIBAgIJAM6l2jUG56pLMA0GCSqGSIb3DQEBCwUAMIGLMQswCQYD
269VQQGEwJVUzELMAkGA1UECBMCQ0ExEjAQBgNVBAcTCVNvbWV3aGVyZTETMBEGA1UE
270ChMKQ2llbmEgSW5jLjEeMBwGCSqGSIb3DQEJARYPYWRtaW5AY2llbmEuY29tMSYw
271JAYDVQQDEx1FeGFtcGxlIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjAzMTEx
272ODUzMzVaFw0xNzAzMDYxODUzMzVaMIGLMQswCQYDVQQGEwJVUzELMAkGA1UECBMC
273Q0ExEjAQBgNVBAcTCVNvbWV3aGVyZTETMBEGA1UEChMKQ2llbmEgSW5jLjEeMBwG
274CSqGSIb3DQEJARYPYWRtaW5AY2llbmEuY29tMSYwJAYDVQQDEx1FeGFtcGxlIENl
275cnRpZmljYXRlIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
276ggEBAL9Jv54TkqycL3U2Fdd/y5NXdnPVXwAVV3m6I3eIffVCv8eS+mwlbl9dnbjo
277qqlGEgA3sEg5HtnKoW81l3PSyV/YaqzUzbcpDlgWlbNkFQ3nVxh61gSU34Fc4h/W
278plSvCkwGSbV5udLtEe6S9IflP2Fu/eXa9vmUtoPqDk66p9U/nWVf2H1GJy7XanWg
279wke+HpQvbzoSfPJS0e5Rm9KErrzaIkJpqt7soW+OjVJitUax7h45RYY1HHHlbMQ0
280ndWW8UDsCxFQO6d7nsijCzY69Y8HarH4mbVtqhg3KJevxD9UMRy6gdtPMDZLah1c
281LHRu14ucOK4aF8oICOgtcD06auUCAwEAAaOCASwwggEoMB0GA1UdDgQWBBQwEs0m
282c8HARTVp21wtiwgav5biqjCBwAYDVR0jBIG4MIG1gBQwEs0mc8HARTVp21wtiwga
283v5biqqGBkaSBjjCBizELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRIwEAYDVQQH
284EwlTb21ld2hlcmUxEzARBgNVBAoTCkNpZW5hIEluYy4xHjAcBgkqhkiG9w0BCQEW
285D2FkbWluQGNpZW5hLmNvbTEmMCQGA1UEAxMdRXhhbXBsZSBDZXJ0aWZpY2F0ZSBB
286dXRob3JpdHmCCQDOpdo1BueqSzAMBgNVHRMEBTADAQH/MDYGA1UdHwQvMC0wK6Ap
287oCeGJWh0dHA6Ly93d3cuZXhhbXBsZS5jb20vZXhhbXBsZV9jYS5jcmwwDQYJKoZI
288hvcNAQELBQADggEBAK+fyAFO8CbH35P5mOX+5wf7+AeC+5pwaFcoCV0zlfwniANp
289jISgcIX9rcetLxeYRAO5com3+qLdd9dGVNL0kwufH4QhlSPErG7OLHHAs4JWVhUo
290bH3lK9lgFVlnCDBtQhslzqScR64SCicWcQEjv3ZMZsJwYLvl8unSaKz4+LVPeJ2L
291opCpmZw/V/S2NhBbe3QjTiRPmDev2gbaO4GCfi/6sCDU7UO3o8KryrkeeMIiFIej
292gfwn9fovmpeqCEyupy2JNNUTJibEuFknwx7JAX+htPL27nEgwV1FYtwI3qLiZqkM
293729wo9cFSslJNZBu+GsBP5LszQSuvNTDWytV+qY=
294-----END CERTIFICATE-----'''
295 def __init__(self):
296 pass
297 def setUp(self):
298 self.onos_ctrl = OnosCtrl(self.eap_app)
299 self.onos_aaa_config()
300
301 def onos_aaa_config(self):
302 aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password',
303 'radiusIp': '172.17.0.2' } } } }
304 radius_ip = os.getenv('ONOS_AAA_IP') or '172.17.0.2'
305 aaa_dict['apps']['org.onosproject.aaa']['AAA']['radiusIp'] = radius_ip
306 self.onos_ctrl.activate()
307 time.sleep(2)
308 self.onos_load_config(aaa_dict)
309
310 def onos_load_config(self, config):
311 log.info('onos load config is %s'%config)
312 status, code = OnosCtrl.config(config)
313 if status is False:
314 log.info('JSON request returned status %d' %code)
315 assert_equal(status, True)
316 time.sleep(2)
317
318
319class cluster_flows():
320
321 PORT_TX_DEFAULT = 2
322 PORT_RX_DEFAULT = 1
323 INTF_TX_DEFAULT = 'veth2'
324 INTF_RX_DEFAULT = 'veth0'
325 default_port_map = {
326 PORT_TX_DEFAULT : INTF_TX_DEFAULT,
327 PORT_RX_DEFAULT : INTF_RX_DEFAULT,
328 INTF_TX_DEFAULT : PORT_TX_DEFAULT,
329 INTF_RX_DEFAULT : PORT_RX_DEFAULT
330 }
331 app = 'org.onosproject.cli'
332
333 def incmac(self, mac):
334 tmp = str(hex(int('0x'+mac,16)+1).split('x')[1])
335 mac = '0'+ tmp if len(tmp) < 2 else tmp
336 return mac
337
338 def next_mac(self, mac):
339 mac = mac.split(":")
340 mac[5] = self.incmac(mac[5])
341
342 if len(mac[5]) > 2:
343 mac[0] = self.incmac(mac[0])
344 mac[5] = '01'
345
346 if len(mac[0]) > 2:
347 mac[0] = '01'
348 mac[1] = self.incmac(mac[1])
349 mac[5] = '01'
350 return ':'.join(mac)
351
352 def to_egress_mac(cls, mac):
353 mac = mac.split(":")
354 mac[4] = '01'
355
356 return ':'.join(mac)
357
358 def inc_ip(self, ip, i):
359
360 ip[i] =str(int(ip[i])+1)
361 return '.'.join(ip)
362
363
364 def next_ip(self, ip):
365
366 lst = ip.split('.')
367 for i in (3,0,-1):
368 if int(lst[i]) < 255:
369 return self.inc_ip(lst, i)
370 elif int(lst[i]) == 255:
371 lst[i] = '0'
372 if int(lst[i-1]) < 255:
373 return self.inc_ip(lst,i-1)
374 elif int(lst[i-2]) < 255:
375 lst[i-1] = '0'
376 return self.inc_ip(lst,i-2)
377 else:
378 break
379
380 def randomip(self,start_ip = '10.10.0.1', end_ip = '10.10.0.100'):
381 start = list(map(int, start_ip.split(".")))
382 end = list(map(int, end_ip.split(".")))
383 temp = start
384 ip_range = []
385 ip_range.append(start_ip)
386 while temp != end:
387 start[3] += 1
388 for i in (3, 2, 1):
389 if temp[i] == 255:
390 temp[i] = 0
391 temp[i-1] += 1
392 ip_range.append(".".join(map(str, temp)))
393 return random.choice(ip_range)
394
395 def ip_range(self,start_ip = '10.10.0.1', end_ip = '10.10.0.100'):
396 start = list(map(int, start_ip.split(".")))
397 end = list(map(int, end_ip.split(".")))
398 temp = start
399 ip_range = []
400 ip_range.append(start_ip)
401 while temp != end:
402 start[3] += 1
403 for i in (3, 2, 1):
404 if temp[i] == 255:
405 temp[i] = 0
406 temp[i-1] += 1
407 ip_range.append(".".join(map(str, temp)))
408 return ip_range
409
410 def to_egress_ip(self, ip):
411 lst=ip.split('.')
412 lst[0] = '182'
413 return '.'.join(lst)
414
415 @classmethod
416 def setUpClass(cls):
417 cls.olt = OltConfig()
418 cls.port_map, _ = cls.olt.olt_port_map()
419 if not cls.port_map:
420 cls.port_map = cls.default_port_map
421 cls.device_id = OnosCtrl.get_device_id()
422
423class cluster_proxyarp():
424 apps = ('org.onosproject.vrouter','org.onosproject.proxyarp')
425 device_id = 'of:' + get_mac()
426 device_dict = { "devices" : {
427 "{}".format(device_id) : {
428 "basic" : {
429 "driver" : "softrouter"
430 }
431 }
432 },
433 }
434 test_path = os.path.dirname(os.path.realpath(__file__))
435 onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
436 GATEWAY = '192.168.10.50'
437 INGRESS_PORT = 1
438 EGRESS_PORT = 2
439 MAX_PORTS = 100
440 hosts_list = [ ('192.168.10.1', '00:00:00:00:00:01'), ('192.168.11.1', '00:00:00:00:02:01'), ]
441
442 olt_conf_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../setup/olt_config.json')
443
444 @classmethod
445 def setUpClass(cls):
446 cls.olt = OltConfig()
447 cls.port_map, _ = cls.olt.olt_port_map()
448 print('port map in proxyarp setUpClass is %s'%cls.port_map)
449 if not cls.port_map:
450 cls.port_map = g_subscriber_port_map
451 time.sleep(3)
452 cls.load_device_id()
453
454 @classmethod
455 def load_device_id(cls):
456 did = OnosCtrl.get_device_id()
457 cls.device_id = did
458 cls.device_dict = { "devices" : {
459 "{}".format(did) : {
460 "basic" : {
461 "driver" : "softrouter"
462 }
463 }
464 },
465 }
466 def cliEnter(self):
467 retries = 0
468 while retries < 3:
469 self.cli = OnosCliDriver(connect = True)
470 if self.cli.handle:
471 break
472 else:
473 retries += 1
474 time.sleep(2)
475
476 def cliExit(self):
477 self.cli.disconnect()
478
479 @classmethod
480 def interface_config_load(cls, interface_cfg = None):
481 if type(interface_cfg) is tuple:
482 res = []
483 for v in interface_cfg:
484 if type(v) == list:
485 pass
486 else:
487 res += v.items()
488 config = dict(res)
489 else:
490 config = interface_cfg
491 cfg = json.dumps(config)
492 with open('{}/network-cfg.json'.format(cls.onos_config_path), 'w') as f:
493 f.write(cfg)
494 return cord_test_onos_restart(config=config)
495
496 @classmethod
497 def host_config_load(cls, host_config = None):
498 for host in host_config:
499 status, code = OnosCtrl.host_config(host)
500 if status is False:
501 log.info('JSON request returned status %d' %code)
502 assert_equal(status, True)
503
504 @classmethod
505 def generate_interface_config(cls, hosts = 1):
506 num = 0
507 start_host = ( 192 << 24) | ( 168 << 16) | (10 << 8) | 0
508 end_host = ( 200 << 24 ) | (168 << 16) | (10 << 8) | 0
509 ports_dict = { 'ports' : {} }
510 interface_list = []
511 hosts_list = []
512 for n in xrange(start_host, end_host, 256):
513 port_map = ports_dict['ports']
514 port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
515 device_port_key = '{0}/{1}'.format(cls.device_id, port)
516 try:
517 interfaces = port_map[device_port_key]['interfaces']
518 except:
519 port_map[device_port_key] = { 'interfaces' : [] }
520 interfaces = port_map[device_port_key]['interfaces']
521 ip = n + 1
522 host_ip = n + 2
523 ips = '%d.%d.%d.%d/24'%( (ip >> 24) & 0xff, ( (ip >> 16) & 0xff ), ( (ip >> 8 ) & 0xff ), ip & 0xff)
524 host = '%d.%d.%d.%d' % ( (host_ip >> 24) & 0xff, ( ( host_ip >> 16) & 0xff ), ( (host_ip >> 8 ) & 0xff ), host_ip & 0xff )
525 mac = RandMAC()._fix()
526 hosts_list.append((host, mac))
527 if num < cls.MAX_PORTS - 1:
528 interface_dict = { 'name' : 'b1-{}'.format(port), 'ips': [ips], 'mac' : mac }
529 interfaces.append(interface_dict)
530 interface_list.append(interface_dict['name'])
531 else:
532 interfaces[0]['ips'].append(ips)
533 num += 1
534 if num == hosts:
535 break
536 cls.hosts_list = hosts_list
537 return (cls.device_dict, ports_dict, hosts_list)
538
539 @classmethod
540 def generate_host_config(cls):
541 num = 0
542 hosts_dict = {}
543 for host, mac in cls.hosts_list:
544 port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
545 hosts_dict[host] = {'mac':mac, 'vlan':'none', 'ipAddresses':[host], 'location':{ 'elementId' : '{}'.format(cls.device_id), 'port': port}}
546 num += 1
547 return hosts_dict.values()
548
549 @classmethod
550 def proxyarp_activate(cls, deactivate = False):
551 app = 'org.onosproject.proxyarp'
552 onos_ctrl = OnosCtrl(app)
553 if deactivate is True:
554 onos_ctrl.deactivate()
555 else:
556 onos_ctrl.activate()
557 time.sleep(3)
558
559 @classmethod
560 def proxyarp_config(cls, hosts = 1):
561 proxyarp_configs = cls.generate_interface_config(hosts = hosts)
562 cls.interface_config_load(interface_cfg = proxyarp_configs)
563 hostcfg = cls.generate_host_config()
564 cls.host_config_load(host_config = hostcfg)
565 return proxyarp_configs
566
567 def proxyarp_arpreply_verify(self, ingress, hostip, hostmac, PositiveTest=True):
568 #log.info('verifying arp reply for host ip %s host mac %s on interface %s'%(hostip ,hostmac ,self.port_map[ingress]))
569 self.success = False
570 def recv_task():
571 def recv_cb(pkt):
572 log.info('Arp Reply seen with source Mac is %s' %(pkt[ARP].hwsrc))
573 self.success = True if PositiveTest == True else False
574 sniff(count=1, timeout=2, lfilter = lambda p: ARP in p and p[ARP].op == 2 and p[ARP].hwsrc == hostmac,
575 prn = recv_cb, iface = self.port_map[ingress])
576 t = threading.Thread(target = recv_task)
577 t.start()
578 pkt = (Ether(dst = 'ff:ff:ff:ff:ff:ff')/ARP(op=1,pdst=hostip))
579 log.info('sending arp request for dest ip %s on interface %s' %
580 (hostip, self.port_map[ingress]))
581 sendp( pkt, count = 10, iface = self.port_map[ingress])
582 t.join()
583 if PositiveTest:
584 assert_equal(self.success, True)
585 else:
586 assert_equal(self.success, False)
587
588 def proxyarp_hosts_verify(self, hosts = 1,PositiveTest = True):
589 log.info('verifying arp reply for host ip host mac on interface %s'%(self.port_map[2]))
590 _,_,hosts_config = self.proxyarp_config(hosts = hosts)
591 log.info('\nhosts_config %s and its type %s'%(hosts_config,type(hosts_config)))
592 self.cliEnter()
593 connected_hosts = json.loads(self.cli.hosts(jsonFormat = True))
594 log.info('Discovered hosts: %s' %connected_hosts)
595 #We read from cli if we expect less number of routes to avoid cli timeouts
596 if hosts <= 10000:
597 assert_equal(len(connected_hosts), hosts)
598 ingress = hosts+1
599 for hostip, hostmac in hosts_config:
600 self.proxyarp_arpreply_verify(ingress,hostip,hostmac,PositiveTest = PositiveTest)
601 time.sleep(1)
602 self.cliExit()
603 return True
604
605class cluster_vrouter(object):
606 apps = ('org.onosproject.vrouter', 'org.onosproject.fwd')
607 device_id = 'of:' + get_mac()
608 vrouter_device_dict = { "devices" : {
609 "{}".format(device_id) : {
610 "basic" : {
611 "driver" : "softrouter"
612 }
613 }
614 },
615 }
616 zebra_conf = '''
617password zebra
618log stdout
619service advanced-vty
620!
621!debug zebra rib
622!debug zebra kernel
623!debug zebra fpm
624!
625!interface eth1
626! ip address 10.10.0.3/16
627line vty
628 exec-timeout 0 0
629'''
630 test_path = os.path.dirname(os.path.realpath(__file__))
631 quagga_config_path = os.path.join(test_path, '..', 'setup/quagga-config')
632 onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
633 GATEWAY = '192.168.10.50'
634 INGRESS_PORT = 1
635 EGRESS_PORT = 2
636 MAX_PORTS = 100
637 peer_list = [ ('192.168.10.1', '00:00:00:00:00:01'), ('192.168.11.1', '00:00:00:00:02:01'), ]
638 network_list = []
639 network_mask = 24
640 default_routes_address = ('11.10.10.0/24',)
641 default_peer_address = peer_list
642 quagga_ip = os.getenv('QUAGGA_IP')
643
644 @classmethod
645 def setUpClass(cls):
646 ''' Activate the vrouter apps'''
647 cls.olt = OltConfig()
648 cls.port_map, _ = cls.olt.olt_port_map()
649 if not cls.port_map:
650 cls.port_map = g_subscriber_port_map
651 time.sleep(3)
652 cls.load_device_id()
653
654 @classmethod
655 def tearDownClass(cls):
656 '''Deactivate the vrouter apps'''
657 #cls.vrouter_host_unload()
658 cls.start_onos(network_cfg = {})
659 #cls.vrouter_activate(cls, deactivate = True)
660
661
662 @classmethod
663 def load_device_id(cls):
664 did = OnosCtrl.get_device_id()
665 cls.device_id = did
666 cls.vrouter_device_dict = { "devices" : {
667 "{}".format(did) : {
668 "basic" : {
669 "driver" : "softrouter"
670 }
671 }
672 },
673 }
674
675 def cliEnter(self):
676 retries = 0
677 while retries < 3:
678 self.cli = OnosCliDriver(connect = True)
679 if self.cli.handle:
680 break
681 else:
682 retries += 1
683 time.sleep(2)
684
685 def cliExit(self):
686 self.cli.disconnect()
687
688 @classmethod
689 def onos_load_config(cls, config):
690 status, code = OnosCtrl.config(config)
691 if status is False:
692 log.info('JSON request returned status %d' %code)
693 assert_equal(status, True)
694
695 @classmethod
696 def vrouter_config_get(cls, networks = 4, peers = 1, peer_address = None,
697 route_update = None, router_address = None):
698 vrouter_configs = cls.generate_vrouter_conf(networks = networks, peers = peers,
699 peer_address = peer_address, router_address = router_address)
700 return vrouter_configs
701
702 @classmethod
703 def vrouter_host_load(cls, peer_address = None):
704 #cls.setUpClass()
705 index = 1
706 peer_info = peer_address if peer_address is not None else cls.peer_list
707
708 for host,_ in peer_info:
709 iface = cls.port_map[index]
710 index += 1
711 log.info('Assigning ip %s to interface %s' %(host, iface))
712 config_cmds = ( 'ifconfig {} 0'.format(iface),
713 'ifconfig {0} {1}'.format(iface, host),
714 'arping -I {0} {1} -c 2'.format(iface, host),
715 )
716 for cmd in config_cmds:
717 os.system(cmd)
718
719 @classmethod
720 def vrouter_host_unload(cls, peer_address = None):
721 index = 1
722 peer_info = peer_address if peer_address is not None else cls.peer_list
723
724 for host,_ in peer_info:
725 iface = cls.port_map[index]
726 index += 1
727 config_cmds = ('ifconfig {} 0'.format(iface), )
728 for cmd in config_cmds:
729 os.system(cmd)
730
731 @classmethod
732 def start_onos(cls, network_cfg = None):
733 if type(network_cfg) is tuple:
734 res = []
735 for v in network_cfg:
736 res += v.items()
737 config = dict(res)
738 else:
739 config = network_cfg
740 log.info('Restarting ONOS with new network configuration %s'%config)
741 #return CordTestServer().restart_onos(config)
742 return cord_test_onos_restart(config = config)
743
744 @classmethod
745 def start_quagga(cls, networks = 4, peer_address = None, router_address = None):
746 log.info('Restarting Quagga container with configuration for %d networks' %(networks))
747 config = cls.generate_conf(networks = networks, peer_address = peer_address, router_address = router_address)
748 if networks <= 10000:
749 boot_delay = 25
750 else:
751 delay_map = [60, 100, 150, 200, 300, 450, 600, 800, 1000, 1200]
752 n = min(networks/100000, len(delay_map)-1)
753 boot_delay = delay_map[n]
754 cord_test_quagga_restart(config = config, boot_delay = boot_delay)
755
756 @classmethod
757 def generate_vrouter_conf(cls, networks = 4, peers = 1, peer_address = None, router_address = None):
758 num = 0
759 if peer_address is None:
760 start_peer = ( 192 << 24) | ( 168 << 16) | (10 << 8) | 0
761 end_peer = ( 200 << 24 ) | (168 << 16) | (10 << 8) | 0
762 else:
763 ip = peer_address[0][0]
764 start_ip = ip.split('.')
765 start_peer = ( int(start_ip[0]) << 24) | ( int(start_ip[1]) << 16) | ( int(start_ip[2]) << 8) | 0
766 end_peer = ((int(start_ip[0]) + 8) << 24 ) | (int(start_ip[1]) << 16) | (int(start_ip[2]) << 8) | 0
767 local_network = end_peer + 1
768 ports_dict = { 'ports' : {} }
769 interface_list = []
770 peer_list = []
771 for n in xrange(start_peer, end_peer, 256):
772 port_map = ports_dict['ports']
773 port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
774 device_port_key = '{0}/{1}'.format(cls.device_id, port)
775 try:
776 interfaces = port_map[device_port_key]['interfaces']
777 except:
778 port_map[device_port_key] = { 'interfaces' : [] }
779 interfaces = port_map[device_port_key]['interfaces']
780 ip = n + 2
781 peer_ip = n + 1
782 ips = '%d.%d.%d.%d/24'%( (ip >> 24) & 0xff, ( (ip >> 16) & 0xff ), ( (ip >> 8 ) & 0xff ), ip & 0xff)
783 peer = '%d.%d.%d.%d' % ( (peer_ip >> 24) & 0xff, ( ( peer_ip >> 16) & 0xff ), ( (peer_ip >> 8 ) & 0xff ), peer_ip & 0xff )
784 mac = RandMAC()._fix()
785 peer_list.append((peer, mac))
786 if num < cls.MAX_PORTS - 1:
787 interface_dict = { 'name' : 'b1-{}'.format(port), 'ips': [ips], 'mac' : mac }
788 interfaces.append(interface_dict)
789 interface_list.append(interface_dict['name'])
790 else:
791 interfaces[0]['ips'].append(ips)
792 num += 1
793 if num == peers:
794 break
795 quagga_dict = { 'apps': { 'org.onosproject.router' : { 'router' : {}, 'bgp' : { 'bgpSpeakers' : [] } } } }
796 quagga_router_dict = quagga_dict['apps']['org.onosproject.router']['router']
797 quagga_router_dict['ospfEnabled'] = True
798 quagga_router_dict['interfaces'] = interface_list
799 quagga_router_dict['controlPlaneConnectPoint'] = '{0}/{1}'.format(cls.device_id, peers + 1)
800
801 #bgp_speaker_dict = { 'apps': { 'org.onosproject.router' : { 'bgp' : { 'bgpSpeakers' : [] } } } }
802 bgp_speakers_list = quagga_dict['apps']['org.onosproject.router']['bgp']['bgpSpeakers']
803 speaker_dict = {}
804 speaker_dict['name'] = 'bgp{}'.format(peers+1)
805 speaker_dict['connectPoint'] = '{0}/{1}'.format(cls.device_id, peers + 1)
806 speaker_dict['peers'] = peer_list
807 bgp_speakers_list.append(speaker_dict)
808 cls.peer_list = peer_list
809 return (cls.vrouter_device_dict, ports_dict, quagga_dict)
810
811 @classmethod
812 def generate_conf(cls, networks = 4, peer_address = None, router_address = None):
813 num = 0
814 if router_address is None:
815 start_network = ( 11 << 24) | ( 10 << 16) | ( 10 << 8) | 0
816 end_network = ( 172 << 24 ) | ( 0 << 16) | (0 << 8) | 0
817 network_mask = 24
818 else:
819 ip = router_address
820 start_ip = ip.split('.')
821 network_mask = int(start_ip[3].split('/')[1])
822 start_ip[3] = (start_ip[3].split('/'))[0]
823 start_network = (int(start_ip[0]) << 24) | ( int(start_ip[1]) << 16) | ( int(start_ip[2]) << 8) | 0
824 end_network = (172 << 24 ) | (int(start_ip[1]) << 16) | (int(start_ip[2]) << 8) | 0
825 net_list = []
826 peer_list = peer_address if peer_address is not None else cls.peer_list
827 network_list = []
828 for n in xrange(start_network, end_network, 256):
829 net = '%d.%d.%d.0'%( (n >> 24) & 0xff, ( ( n >> 16) & 0xff ), ( (n >> 8 ) & 0xff ) )
830 network_list.append(net)
831 gateway = peer_list[num % len(peer_list)][0]
832 net_route = 'ip route {0}/{1} {2}'.format(net, network_mask, gateway)
833 net_list.append(net_route)
834 num += 1
835 if num == networks:
836 break
837 cls.network_list = network_list
838 cls.network_mask = network_mask
839 zebra_routes = '\n'.join(net_list)
840 #log.info('Zebra routes: \n:%s\n' %cls.zebra_conf + zebra_routes)
841 return cls.zebra_conf + zebra_routes
842
843 @classmethod
844 def vrouter_activate(cls, deactivate = False):
845 app = 'org.onosproject.vrouter'
846 onos_ctrl = OnosCtrl(app)
847 if deactivate is True:
848 onos_ctrl.deactivate()
849 else:
850 onos_ctrl.activate()
851 time.sleep(3)
852
853 @classmethod
854 def vrouter_configure(cls, networks = 4, peers = 1, peer_address = None,
855 route_update = None, router_address = None, time_expire = None, adding_new_routes = None):
856 vrouter_configs = cls.vrouter_config_get(networks = networks, peers = peers,
857 peer_address = peer_address, route_update = route_update)
858 cls.start_onos(network_cfg = vrouter_configs)
859 cls.vrouter_host_load()
860 ##Start quagga
861 cls.start_quagga(networks = networks, peer_address = peer_address, router_address = router_address)
862 return vrouter_configs
863
864 def vrouter_port_send_recv(self, ingress, egress, dst_mac, dst_ip, positive_test = True):
865 src_mac = '00:00:00:00:00:02'
866 src_ip = '1.1.1.1'
867 self.success = False if positive_test else True
868 timeout = 10 if positive_test else 1
869 count = 2 if positive_test else 1
870 self.start_sending = True
871 def recv_task():
872 def recv_cb(pkt):
873 log.info('Pkt seen with ingress ip %s, egress ip %s' %(pkt[IP].src, pkt[IP].dst))
874 self.success = True if positive_test else False
875 sniff(count=count, timeout=timeout,
876 lfilter = lambda p: IP in p and p[IP].dst == dst_ip and p[IP].src == src_ip,
877 prn = recv_cb, iface = self.port_map[ingress])
878 self.start_sending = False
879
880 t = threading.Thread(target = recv_task)
881 t.start()
882 L2 = Ether(src = src_mac, dst = dst_mac)
883 L3 = IP(src = src_ip, dst = dst_ip)
884 pkt = L2/L3
885 log.info('Sending a packet with dst ip %s, dst mac %s on port %s to verify if flows are correct' %
886 (dst_ip, dst_mac, self.port_map[egress]))
887 while self.start_sending is True:
888 sendp(pkt, count=50, iface = self.port_map[egress])
889 t.join()
890 assert_equal(self.success, True)
891
892 def vrouter_traffic_verify(self, positive_test = True, peer_address = None):
893 if peer_address is None:
894 peers = len(self.peer_list)
895 peer_list = self.peer_list
896 else:
897 peers = len(peer_address)
898 peer_list = peer_address
899 egress = peers + 1
900 num = 0
901 num_hosts = 5 if positive_test else 1
902 src_mac = '00:00:00:00:00:02'
903 src_ip = '1.1.1.1'
904 if self.network_mask != 24:
905 peers = 1
906 for network in self.network_list:
907 num_ips = num_hosts
908 octets = network.split('.')
909 for i in xrange(num_ips):
910 octets[-1] = str(int(octets[-1]) + 1)
911 dst_ip = '.'.join(octets)
912 dst_mac = peer_list[ num % peers ] [1]
913 port = (num % peers)
914 ingress = port + 1
915 #Since peers are on the same network
916 ##Verify if flows are setup by sending traffic across
917 self.vrouter_port_send_recv(ingress, egress, dst_mac, dst_ip, positive_test = positive_test)
918 num += 1
919
920 def vrouter_network_verify(self, networks, peers = 1, positive_test = True,
921 start_network = None, start_peer_address = None, route_update = None,
922 invalid_peers = None, time_expire = None, unreachable_route_traffic = None,
923 deactivate_activate_vrouter = None, adding_new_routes = None):
924
925 _, ports_map, egress_map = self.vrouter_configure(networks = networks, peers = peers,
926 peer_address = start_peer_address,
927 route_update = route_update,
928 router_address = start_network,
929 time_expire = time_expire,
930 adding_new_routes = adding_new_routes)
931 self.cliEnter()
932 ##Now verify
933 hosts = json.loads(self.cli.hosts(jsonFormat = True))
934 log.info('Discovered hosts: %s' %hosts)
935 ##We read from cli if we expect less number of routes to avoid cli timeouts
936 if networks <= 10000:
937 routes = json.loads(self.cli.routes(jsonFormat = True))
938 #log.info('Routes: %s' %routes)
939 if start_network is not None:
940 if start_network.split('/')[1] is 24:
941 assert_equal(len(routes['routes4']), networks)
942 if start_network.split('/')[1] is not 24:
943 assert_equal(len(routes['routes4']), 1)
944 if start_network is None and invalid_peers is None:
945 assert_equal(len(routes['routes4']), networks)
946 if invalid_peers is not None:
947 assert_equal(len(routes['routes4']), 0)
948 flows = json.loads(self.cli.flows(jsonFormat = True))
949 flows = filter(lambda f: f['flows'], flows)
950 #log.info('Flows: %s' %flows)
951 assert_not_equal(len(flows), 0)
952 if invalid_peers is None:
953 self.vrouter_traffic_verify()
954 if positive_test is False:
955 self.vrouter_network_verify_negative(networks, peers = peers)
956 if time_expire is True:
957 self.start_quagga(networks = networks, peer_address = start_peer_address, router_address = '12.10.10.1/24')
958 self.vrouter_traffic_verify()
959 if unreachable_route_traffic is True:
960 network_list_backup = self.network_list
961 self.network_list = ['2.2.2.2','3.3.3.3','4.4.4.4','5.5.5.5']
962 self.vrouter_traffic_verify(positive_test = False)
963 self.network_list = network_list_backup
964 if deactivate_activate_vrouter is True:
965 log.info('Deactivating vrouter app in ONOS controller for negative scenario')
966 self.vrouter_activate(deactivate = True)
967 #routes = json.loads(self.cli.routes(jsonFormat = False, cmd_exist = False))
968 #assert_equal(len(routes['routes4']), 'Command not found')
969 log.info('Activating vrouter app again in ONOS controller for negative scenario')
970 self.vrouter_activate(deactivate = False)
971 routes = json.loads(self.cli.routes(jsonFormat = True))
972 assert_equal(len(routes['routes4']), networks)
973 self.vrouter_traffic_verify()
974 self.cliExit()
975 return True
976
977 def vrouter_network_verify_negative(self, networks, peers = 1):
978 ##Stop quagga. Test traffic again to see if flows were removed
979 log.info('Stopping Quagga container')
980 cord_test_quagga_stop()
981 if networks <= 10000:
982 routes = json.loads(self.cli.routes(jsonFormat = True))
983 #Verify routes have been removed
984 if routes and routes.has_key('routes4'):
985 assert_equal(len(routes['routes4']), 0)
986 self.vrouter_traffic_verify(positive_test = False)
987 log.info('OVS flows have been removed successfully after Quagga was stopped')
988 self.start_quagga(networks = networks)
989 ##Verify the flows again after restarting quagga back
990 if networks <= 10000:
991 routes = json.loads(self.cli.routes(jsonFormat = True))
992 assert_equal(len(routes['routes4']), networks)
993 self.vrouter_traffic_verify()
994 log.info('OVS flows have been successfully reinstalled after Quagga was restarted')
995
996 def quagga_shell(self, cmd):
997 shell_cmds = ('vtysh', '"conf t"', '"{}"'.format(cmd))
998 quagga_cmd = ' -c '.join(shell_cmds)
999
1000 return cord_test_quagga_shell(quagga_cmd)
1001
1002class cluster_acl(object):
1003 app = ('org.onosproject.acl')
1004 device_id = 'of:' + get_mac('ovsbr0')
1005 test_path = os.path.dirname(os.path.realpath(__file__))
1006 onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
1007 GATEWAY = '192.168.10.50'
1008 INGRESS_PORT = 1
1009 EGRESS_PORT = 2
1010 ingress_iface = 1
1011 egress_iface = 2
1012 MAX_PORTS = 100
1013 CURRENT_PORT_NUM = egress_iface
1014 ACL_SRC_IP = '192.168.20.3/32'
1015 ACL_DST_IP = '192.168.30.2/32'
1016 ACL_SRC_IP_RULE_2 = '192.168.40.3/32'
1017 ACL_DST_IP_RULE_2 = '192.168.50.2/32'
1018 ACL_SRC_IP_PREFIX_24 = '192.168.20.3/24'
1019 ACL_DST_IP_PREFIX_24 = '192.168.30.2/24'
1020 HOST_DST_IP = '192.168.30.0/24'
1021 HOST_DST_IP_RULE_2 = '192.168.50.0/24'
1022
1023 @classmethod
1024 def setUpClass(cls):
1025 cls.olt = OltConfig()
1026 cls.port_map,_ = cls.olt.olt_port_map()
1027 if not cls.port_map:
1028 cls.port_map = g_subscriber_port_map
1029 time.sleep(3)
1030 log.info('port_map = %s'%cls.port_map[1] )
1031
1032 @classmethod
1033 def tearDownClass(cls):
1034 '''Deactivate the acl app'''
1035 def setUp(self):
1036 self.setUpClass()
1037 ''' Activate the acl app'''
1038 self.maxDiff = None ##for assert_equal compare outputs on failure
1039 self.onos_ctrl = OnosCtrl(self.app)
1040 status, _ = self.onos_ctrl.activate()
1041 assert_equal(status, True)
1042 time.sleep(1)
1043 #status, _ = ACLTest.remove_acl_rule()
1044 #log.info('Start setup')
1045 #assert_equal(status, True)
1046
1047 def tearDown(self):
1048 '''Deactivate the acl app'''
1049 log.info('Tear down setup')
1050 self.CURRENT_PORT_NUM = 4
1051
1052 def cliEnter(self):
1053 retries = 0
1054 while retries < 3:
1055 self.cli = OnosCliDriver(connect = True)
1056 if self.cli.handle:
1057 break
1058 else:
1059 retries += 1
1060 time.sleep(2)
1061
1062 def cliExit(self):
1063 self.cli.disconnect()
1064
1065 @classmethod
1066 def acl_hosts_add(cls, dstHostIpMac, egress_iface_count = 1, egress_iface_num = None):
1067 cls.setUpClass()
1068 index = 0
1069 if egress_iface_num is None:
1070 egress_iface_num = cls.egress_iface
1071 for ip,_ in dstHostIpMac:
1072 egress = cls.port_map[egress_iface_num]
1073 log.info('Assigning ip %s to interface %s' %(ip, egress))
1074 config_cmds_egress = ( 'ifconfig {} 0'.format(egress),
1075 'ifconfig {0} up'.format(egress),
1076 'ifconfig {0} {1}'.format(egress, ip),
1077 'arping -I {0} {1} -c 2'.format(egress, ip.split('/')[0]),
1078 'ifconfig {0}'.format(egress),
1079 )
1080 for cmd in config_cmds_egress:
1081 os.system(cmd)
1082 index += 1
1083 if index == egress_iface_count:
1084 break
1085 egress_iface_count += 1
1086 egress_iface_num += 1
1087
1088
1089 @classmethod
1090 def acl_hosts_remove(cls, egress_iface_count = 1, egress_iface_num = None):
1091 cls.setUpClass()
1092 if egress_iface_num is None:
1093 egress_iface_num = cls.egress_iface
1094 n = 0
1095 for n in range(egress_iface_count):
1096 egress = cls.port_map[egress_iface_num]
1097 config_cmds_egress = ('ifconfig {} 0'.format(egress))
1098 os.system(config_cmds_egress)
1099 egress_iface_num += 1
1100
1101 def acl_rule_traffic_send_recv(self, srcMac, dstMac, srcIp, dstIp, ingress =None, egress=None, ip_proto=None, dstPortNum = None, positive_test = True):
1102 self.setUpClass()
1103 if ingress is None:
1104 ingress = self.ingress_iface
1105 if egress is None:
1106 egress = self.egress_iface
1107 ingress = self.port_map[ingress]
1108 egress = self.port_map[egress]
1109 self.success = False if positive_test else True
1110 timeout = 10 if positive_test else 1
1111 count = 2 if positive_test else 1
1112 self.start_sending = True
1113 def recv_task():
1114 def recv_cb(pkt):
1115 log.info('Pkt seen with ingress ip %s, egress ip %s' %(pkt[IP].src, pkt[IP].dst))
1116 self.success = True if positive_test else False
1117 sniff(count=count, timeout=timeout,
1118 lfilter = lambda p: IP in p and p[IP].dst == dstIp.split('/')[0] and p[IP].src == srcIp.split('/')[0],
1119 prn = recv_cb, iface = egress)
1120 self.start_sending = False
1121
1122 t = threading.Thread(target = recv_task)
1123 t.start()
1124 L2 = Ether(src = srcMac, dst = dstMac)
1125 L3 = IP(src = srcIp.split('/')[0], dst = dstIp.split('/')[0])
1126 pkt = L2/L3
1127 log.info('Sending a packet with dst ip %s, src ip %s , dst mac %s src mac %s on port %s to verify if flows are correct' %
1128 (dstIp.split('/')[0], srcIp.split('/')[0], dstMac, srcMac, ingress))
1129 while self.start_sending is True:
1130 sendp(pkt, count=50, iface = ingress)
1131 t.join()
1132 assert_equal(self.success, True)
1133
1134 @classmethod
1135 def onos_load_config(cls, config):
1136 status, code = OnosCtrl.config(config)
1137 if status is False:
1138 log.info('JSON request returned status %d' %code)
1139 assert_equal(status, True)
1140
1141class cluster_dhcprelay(object):
1142 app = 'org.onosproject.dhcprelay'
1143 app_dhcp = 'org.onosproject.dhcp'
1144 relay_interfaces_last = ()
1145 interface_to_mac_map = {}
1146 host_ip_map = {}
1147 test_path = os.path.dirname(os.path.realpath(__file__))
1148 dhcp_data_dir = os.path.join(test_path, '..', 'setup')
1149 olt_conf_file = os.path.join(test_path, '..', 'setup/olt_config.json')
1150 default_config = { 'default-lease-time' : 600, 'max-lease-time' : 7200, }
1151 default_options = [ ('subnet-mask', '255.255.255.0'),
1152 ('broadcast-address', '192.168.1.255'),
1153 ('domain-name-servers', '192.168.1.1'),
1154 ('domain-name', '"mydomain.cord-tester"'),
1155 ]
1156 ##specify the IP for the dhcp interface matching the subnet and subnet config
1157 ##this is done for each interface dhcpd server would be listening on
1158 default_subnet_config = [ ('192.168.1.2',
1159'''
1160subnet 192.168.1.0 netmask 255.255.255.0 {
1161 range 192.168.1.10 192.168.1.100;
1162}
1163'''), ]
1164
1165 lock = threading.Condition()
1166 ip_count = 0
1167 failure_count = 0
1168 start_time = 0
1169 diff = 0
1170
1171 transaction_count = 0
1172 transactions = 0
1173 running_time = 0
1174 total_success = 0
1175 total_failure = 0
1176 onos_restartable = bool(int(os.getenv('ONOS_RESTART', 0)))
1177
1178 @classmethod
1179 def setUpClass(cls):
1180 ''' Activate the dhcprelay app'''
1181 OnosCtrl(cls.app_dhcp).deactivate()
1182 time.sleep(3)
1183 cls.onos_ctrl = OnosCtrl(cls.app)
1184 status, _ = cls.onos_ctrl.activate()
1185 assert_equal(status, True)
1186 time.sleep(3)
1187 cls.dhcp_relay_setup()
1188 ##start dhcpd initially with default config
1189 cls.dhcpd_start()
1190
1191 @classmethod
1192 def tearDownClass(cls):
1193 '''Deactivate the dhcp relay app'''
1194 try:
1195 os.unlink('{}/dhcpd.conf'.format(cls.dhcp_data_dir))
1196 os.unlink('{}/dhcpd.leases'.format(cls.dhcp_data_dir))
1197 except: pass
1198 cls.onos_ctrl.deactivate()
1199 cls.dhcpd_stop()
1200 cls.dhcp_relay_cleanup()
1201
1202 @classmethod
1203 def dhcp_relay_setup(cls):
1204 did = OnosCtrl.get_device_id()
1205 cls.relay_device_id = did
1206 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
1207 cls.port_map, _ = cls.olt.olt_port_map()
1208 if cls.port_map:
1209 ##Per subscriber, we use 1 relay port
1210 try:
1211 relay_port = cls.port_map[cls.port_map['relay_ports'][0]]
1212 except:
1213 relay_port = cls.port_map['uplink']
1214 cls.relay_interface_port = relay_port
1215 cls.relay_interfaces = (cls.port_map[cls.relay_interface_port],)
1216 else:
1217 cls.relay_interface_port = 100
1218 cls.relay_interfaces = (g_subscriber_port_map[cls.relay_interface_port],)
1219 cls.relay_interfaces_last = cls.relay_interfaces
1220 if cls.port_map:
1221 ##generate a ip/mac client virtual interface config for onos
1222 interface_list = []
1223 for port in cls.port_map['ports']:
1224 port_num = cls.port_map[port]
1225 if port_num == cls.port_map['uplink']:
1226 continue
1227 ip = cls.get_host_ip(port_num)
1228 mac = cls.get_mac(port)
1229 interface_list.append((port_num, ip, mac))
1230
1231 #configure dhcp server virtual interface on the same subnet as first client interface
1232 relay_ip = cls.get_host_ip(interface_list[0][0])
1233 relay_mac = cls.get_mac(cls.port_map[cls.relay_interface_port])
1234 interface_list.append((cls.relay_interface_port, relay_ip, relay_mac))
1235 cls.onos_interface_load(interface_list)
1236
1237 @classmethod
1238 def dhcp_relay_cleanup(cls):
1239 ##reset the ONOS port configuration back to default
1240 if cls.onos_restartable is True:
1241 log.info('Cleaning up dhcp relay config by restarting ONOS with default network cfg')
1242 return cord_test_onos_restart(config = {})
1243
1244 @classmethod
1245 def onos_load_config(cls, config):
1246 status, code = OnosCtrl.config(config)
1247 if status is False:
1248 log.info('JSON request returned status %d' %code)
1249 assert_equal(status, True)
1250 time.sleep(2)
1251
1252 @classmethod
1253 def onos_interface_load(cls, interface_list):
1254 interface_dict = { 'ports': {} }
1255 for port_num, ip, mac in interface_list:
1256 port_map = interface_dict['ports']
1257 port = '{}/{}'.format(cls.relay_device_id, port_num)
1258 port_map[port] = { 'interfaces': [] }
1259 interface_list = port_map[port]['interfaces']
1260 interface_map = { 'ips' : [ '{}/{}'.format(ip, 24) ],
1261 'mac' : mac,
1262 'name': 'vir-{}'.format(port_num)
1263 }
1264 interface_list.append(interface_map)
1265
1266 cls.onos_load_config(interface_dict)
1267
1268 @classmethod
1269 def onos_dhcp_relay_load(cls, server_ip, server_mac):
1270 relay_device_map = '{}/{}'.format(cls.relay_device_id, cls.relay_interface_port)
1271 dhcp_dict = {'apps':{'org.onosproject.dhcp-relay':{'dhcprelay':
1272 {'dhcpserverConnectPoint':relay_device_map,
1273 'serverip':server_ip,
1274 'servermac':server_mac
1275 }
1276 }
1277 }
1278 }
1279 cls.onos_load_config(dhcp_dict)
1280
1281 @classmethod
1282 def get_host_ip(cls, port):
1283 if cls.host_ip_map.has_key(port):
1284 return cls.host_ip_map[port]
1285 cls.host_ip_map[port] = '192.168.1.{}'.format(port)
1286 return cls.host_ip_map[port]
1287
1288 @classmethod
1289 def host_load(cls, iface):
1290 '''Have ONOS discover the hosts for dhcp-relay responses'''
1291 port = g_subscriber_port_map[iface]
1292 host = '173.17.1.{}'.format(port)
1293 cmds = ( 'ifconfig {} 0'.format(iface),
1294 'ifconfig {0} {1}'.format(iface, host),
1295 'arping -I {0} {1} -c 2'.format(iface, host),
1296 'ifconfig {} 0'.format(iface), )
1297 for c in cmds:
1298 os.system(c)
1299 @classmethod
1300
1301 def dhcpd_conf_generate(cls, config = default_config, options = default_options,
1302 subnet = default_subnet_config):
1303 conf = ''
1304 for k, v in config.items():
1305 conf += '{} {};\n'.format(k, v)
1306
1307 opts = ''
1308 for k, v in options:
1309 opts += 'option {} {};\n'.format(k, v)
1310
1311 subnet_config = ''
1312 for _, v in subnet:
1313 subnet_config += '{}\n'.format(v)
1314
1315 return '{}{}{}'.format(conf, opts, subnet_config)
1316
1317 @classmethod
1318 def dhcpd_start(cls, intf_list = None,
1319 config = default_config, options = default_options,
1320 subnet = default_subnet_config):
1321 '''Start the dhcpd server by generating the conf file'''
1322 if intf_list is None:
1323 intf_list = cls.relay_interfaces
1324 ##stop dhcpd if already running
1325 cls.dhcpd_stop()
1326 dhcp_conf = cls.dhcpd_conf_generate(config = config, options = options,
1327 subnet = subnet)
1328 ##first touch dhcpd.leases if it doesn't exist
1329 lease_file = '{}/dhcpd.leases'.format(cls.dhcp_data_dir)
1330 if os.access(lease_file, os.F_OK) is False:
1331 with open(lease_file, 'w') as fd: pass
1332
1333 conf_file = '{}/dhcpd.conf'.format(cls.dhcp_data_dir)
1334 with open(conf_file, 'w') as fd:
1335 fd.write(dhcp_conf)
1336
1337 #now configure the dhcpd interfaces for various subnets
1338 index = 0
1339 intf_info = []
1340 for ip,_ in subnet:
1341 intf = intf_list[index]
1342 mac = cls.get_mac(intf)
1343 intf_info.append((ip, mac))
1344 index += 1
1345 os.system('ifconfig {} {}'.format(intf, ip))
1346
1347 intf_str = ','.join(intf_list)
1348 dhcpd_cmd = '/usr/sbin/dhcpd -4 --no-pid -cf {0} -lf {1} {2}'.format(conf_file, lease_file, intf_str)
1349 log.info('Starting DHCPD server with command: %s' %dhcpd_cmd)
1350 ret = os.system(dhcpd_cmd)
1351 assert_equal(ret, 0)
1352 time.sleep(3)
1353 cls.relay_interfaces_last = cls.relay_interfaces
1354 cls.relay_interfaces = intf_list
1355 cls.onos_dhcp_relay_load(*intf_info[0])
1356
1357 @classmethod
1358 def dhcpd_stop(cls):
1359 os.system('pkill -9 dhcpd')
1360 for intf in cls.relay_interfaces:
1361 os.system('ifconfig {} 0'.format(intf))
1362
1363 cls.relay_interfaces = cls.relay_interfaces_last
1364
1365 @classmethod
1366 def get_mac(cls, iface):
1367 if cls.interface_to_mac_map.has_key(iface):
1368 return cls.interface_to_mac_map[iface]
1369 mac = get_mac(iface, pad = 0)
1370 cls.interface_to_mac_map[iface] = mac
1371 return mac
1372
1373 def stats(self,success_rate = False, only_discover = False, iface = 'veth0'):
1374
1375 self.ip_count = 0
1376 self.failure_count = 0
1377 self.start_time = 0
1378 self.diff = 0
1379 self.transaction_count = 0
1380
1381 mac = self.get_mac(iface)
1382 self.host_load(iface)
1383 ##we use the defaults for this test that serves as an example for others
1384 ##You don't need to restart dhcpd server if retaining default config
1385 config = self.default_config
1386 options = self.default_options
1387 subnet = self.default_subnet_config
1388 dhcpd_interface_list = self.relay_interfaces
1389 self.dhcpd_start(intf_list = dhcpd_interface_list,
1390 config = config,
1391 options = options,
1392 subnet = subnet)
1393 self.dhcp = DHCPTest(seed_ip = '182.17.0.1', iface = iface)
1394 self.start_time = time.time()
1395
1396 while self.diff <= 60:
1397
1398 if only_discover:
1399 cip, sip, mac, _ = self.dhcp.only_discover(multiple = True)
1400 log.info('Got dhcp client IP %s from server %s for mac %s' %
1401 (cip, sip, mac))
1402 else:
1403 cip, sip = self.send_recv(mac, update_seed = True, validate = False)
1404
1405 if cip:
1406 self.ip_count +=1
1407 elif cip == None:
1408 self.failure_count += 1
1409 log.info('Failed to get ip')
1410 if success_rate and self.ip_count > 0:
1411 break
1412
1413 self.diff = round(time.time() - self.start_time, 0)
1414
1415 self.transaction_count = round((self.ip_count+self.failure_count)/self.diff, 2)
1416 self.transactions += (self.ip_count+self.failure_count)
1417 self.running_time += self.diff
1418 self.total_success += self.ip_count
1419 self.total_failure += self.failure_count
1420
1421 def send_recv(self, mac, update_seed = False, validate = True):
1422 cip, sip = self.dhcp.discover(mac = mac, update_seed = update_seed)
1423 if validate:
1424 assert_not_equal(cip, None)
1425 assert_not_equal(sip, None)
1426 log.info('Got dhcp client IP %s from server %s for mac %s' %
1427 (cip, sip, self.dhcp.get_mac(cip)[0]))
1428 return cip,sip
1429
1430class Subscriber(Channels):
1431 PORT_TX_DEFAULT = 2
1432 PORT_RX_DEFAULT = 1
1433 INTF_TX_DEFAULT = 'veth2'
1434 INTF_RX_DEFAULT = 'veth0'
1435 STATS_RX = 0
1436 STATS_TX = 1
1437 STATS_JOIN = 2
1438 STATS_LEAVE = 3
1439 SUBSCRIBER_SERVICES = 'DHCP IGMP TLS'
1440 def __init__(self, name = 'sub', service = SUBSCRIBER_SERVICES, port_map = None,
1441 num = 1, channel_start = 0,
1442 tx_port = PORT_TX_DEFAULT, rx_port = PORT_RX_DEFAULT,
1443 iface = INTF_RX_DEFAULT, iface_mcast = INTF_TX_DEFAULT,
1444 mcast_cb = None, loginType = 'wireless'):
1445 self.tx_port = tx_port
1446 self.rx_port = rx_port
1447 self.port_map = port_map or g_subscriber_port_map
1448 try:
1449 self.tx_intf = self.port_map[tx_port]
1450 self.rx_intf = self.port_map[rx_port]
1451 except:
1452 self.tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1453 self.rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1454 log.info('Subscriber %s, rx interface %s, uplink interface %s' %(name, self.rx_intf, self.tx_intf))
1455 Channels.__init__(self, num, channel_start = channel_start,
1456 iface = self.rx_intf, iface_mcast = self.tx_intf, mcast_cb = mcast_cb)
1457 self.name = name
1458 self.service = service
1459 self.service_map = {}
1460 services = self.service.strip().split(' ')
1461 for s in services:
1462 self.service_map[s] = True
1463 self.loginType = loginType
1464 ##start streaming channels
1465 self.join_map = {}
1466 ##accumulated join recv stats
1467 self.join_rx_stats = Stats()
1468 self.recv_timeout = False
1469
1470 def has_service(self, service):
1471 if self.service_map.has_key(service):
1472 return self.service_map[service]
1473 if self.service_map.has_key(service.upper()):
1474 return self.service_map[service.upper()]
1475 return False
1476
1477 def channel_join_update(self, chan, join_time):
1478 self.join_map[chan] = ( Stats(), Stats(), Stats(), Stats() )
1479 self.channel_update(chan, self.STATS_JOIN, 1, t = join_time)
1480 def channel_join(self, chan = 0, delay = 2):
1481 '''Join a channel and create a send/recv stats map'''
1482 if self.join_map.has_key(chan):
1483 del self.join_map[chan]
1484 self.delay = delay
1485 chan, join_time = self.join(chan)
1486 self.channel_join_update(chan, join_time)
1487 return chan
1488
1489 def channel_join_next(self, delay = 2):
1490 '''Joins the next channel leaving the last channel'''
1491 if self.last_chan:
1492 if self.join_map.has_key(self.last_chan):
1493 del self.join_map[self.last_chan]
1494 self.delay = delay
1495 chan, join_time = self.join_next()
1496 self.channel_join_update(chan, join_time)
1497 return chan
1498
1499 def channel_jump(self, delay = 2):
1500 '''Jumps randomly to the next channel leaving the last channel'''
1501 if self.last_chan is not None:
1502 if self.join_map.has_key(self.last_chan):
1503 del self.join_map[self.last_chan]
1504 self.delay = delay
1505 chan, join_time = self.jump()
1506 self.channel_join_update(chan, join_time)
1507 return chan
1508
1509 def channel_leave(self, chan = 0):
1510 if self.join_map.has_key(chan):
1511 del self.join_map[chan]
1512 self.leave(chan)
1513
1514 def channel_update(self, chan, stats_type, packets, t=0):
1515 if type(chan) == type(0):
1516 chan_list = (chan,)
1517 else:
1518 chan_list = chan
1519 for c in chan_list:
1520 if self.join_map.has_key(c):
1521 self.join_map[c][stats_type].update(packets = packets, t = t)
1522 def channel_receive(self, chan, cb = None, count = 1, timeout = 5):
1523 log.info('Subscriber %s on port %s receiving from group %s, channel %d' %
1524 (self.name, self.rx_intf, self.gaddr(chan), chan))
1525 r = self.recv(chan, cb = cb, count = count, timeout = timeout)
1526 if len(r) == 0:
1527 log.info('Subscriber %s on port %s timed out' %(self.name, self.rx_intf))
1528 else:
1529 log.info('Subscriber %s on port %s received %d packets' %(self.name, self.rx_intf, len(r)))
1530 if self.recv_timeout:
1531 ##Negative test case is disabled for now
1532 assert_equal(len(r), 0)
1533
1534 def recv_channel_cb(self, pkt):
1535 ##First verify that we have received the packet for the joined instance
1536 log.info('Packet received for group %s, subscriber %s, port %s' %
1537 (pkt[IP].dst, self.name, self.rx_intf))
1538 if self.recv_timeout:
1539 return
1540 chan = self.caddr(pkt[IP].dst)
1541 assert_equal(chan in self.join_map.keys(), True)
1542 recv_time = monotonic.monotonic() * 1000000
1543 join_time = self.join_map[chan][self.STATS_JOIN].start
1544 delta = recv_time - join_time
1545 self.join_rx_stats.update(packets=1, t = delta, usecs = True)
1546 self.channel_update(chan, self.STATS_RX, 1, t = delta)
1547 log.debug('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
1548
1549class subscriber_pool:
1550
1551 def __init__(self, subscriber, test_cbs):
1552 self.subscriber = subscriber
1553 self.test_cbs = test_cbs
1554
1555 def pool_cb(self):
1556 for cb in self.test_cbs:
1557 if cb:
1558 self.test_status = cb(self.subscriber)
1559 if self.test_status is not True:
1560 ## This is chaning for other sub status has to check again
1561 self.test_status = True
1562 log.info('This service is failed and other services will not run for this subscriber')
1563 break
1564 log.info('This Subscriber is tested for multiple service eligibility ')
1565 self.test_status = True
1566
1567class cluster_subscriber(object):
1568 apps = ('org.opencord.aaa', 'org.onosproject.dhcp')
1569 olt_apps = () #'org.opencord.cordmcast')
1570 vtn_app = 'org.opencord.vtn'
1571 table_app = 'org.ciena.cordigmp'
1572 dhcp_server_config = {
1573 "ip": "10.1.11.50",
1574 "mac": "ca:fe:ca:fe:ca:fe",
1575 "subnet": "255.255.252.0",
1576 "broadcast": "10.1.11.255",
1577 "router": "10.1.8.1",
1578 "domain": "8.8.8.8",
1579 "ttl": "63",
1580 "delay": "2",
1581 "startip": "10.1.11.51",
1582 "endip": "10.1.11.100"
1583 }
1584
1585 aaa_loaded = False
1586 test_path = os.path.dirname(os.path.realpath(__file__))
1587 table_app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-multitable-2.0-SNAPSHOT.oar')
1588 app_file = os.path.join(test_path, '..', 'apps/ciena-cordigmp-2.0-SNAPSHOT.oar')
1589 onos_config_path = os.path.join(test_path, '..', 'setup/onos-config')
1590 olt_conf_file = os.path.join(test_path, '..', 'setup/olt_config.json')
1591 cpqd_path = os.path.join(test_path, '..', 'setup')
1592 ovs_path = cpqd_path
1593 test_services = ('IGMP', 'TRAFFIC')
1594 num_joins = 0
1595 num_subscribers = 0
1596 num_channels = 0
1597 recv_timeout = False
1598 onos_restartable = bool(int(os.getenv('ONOS_RESTART', 0)))
1599
1600 INTF_TX_DEFAULT = 'veth2'
1601 INTF_RX_DEFAULT = 'veth0'
1602 SUBSCRIBER_TIMEOUT = 300
1603 CLIENT_CERT = """-----BEGIN CERTIFICATE-----
1604MIICuDCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMCVVMx
1605CzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTb21ld2hlcmUxEzARBgNVBAoTCkNpZW5h
1606IEluYy4xHjAcBgkqhkiG9w0BCQEWD2FkbWluQGNpZW5hLmNvbTEmMCQGA1UEAxMd
1607RXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwNjA2MjExMjI3WhcN
1608MTcwNjAxMjExMjI3WjBnMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNV
1609BAoTCkNpZW5hIEluYy4xFzAVBgNVBAMUDnVzZXJAY2llbmEuY29tMR0wGwYJKoZI
1610hvcNAQkBFg51c2VyQGNpZW5hLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
1611gYEAwvXiSzb9LZ6c7uNziUfKvoHO7wu/uiFC5YUpXbmVGuGZizbVrny0xnR85Dfe
1612+9R4diansfDhIhzOUl1XjN3YDeSS9OeF5YWNNE8XDhlz2d3rVzaN6hIhdotBkUjg
1613rUewjTg5OFR31QEyG3v8xR3CLgiE9xQELjZbSA07pD79zuUCAwEAAaNPME0wEwYD
1614VR0lBAwwCgYIKwYBBQUHAwIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL3d3dy5l
1615eGFtcGxlLmNvbS9leGFtcGxlX2NhLmNybDANBgkqhkiG9w0BAQUFAAOBgQDAjkrY
16166tDChmKbvr8w6Du/t8vHjTCoCIocHTN0qzWOeb1YsAGX89+TrWIuO1dFyYd+Z0KC
1617PDKB5j/ygml9Na+AklSYAVJIjvlzXKZrOaPmhZqDufi+rXWti/utVqY4VMW2+HKC
1618nXp37qWeuFLGyR1519Y1d6F/5XzqmvbwURuEug==
1619-----END CERTIFICATE-----"""
1620
1621 CLIENT_CERT_INVALID = '''-----BEGIN CERTIFICATE-----
1622MIIDvTCCAqWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMCVVMx
1623CzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTb21ld2hlcmUxEzARBgNVBAoTCkNpZW5h
1624IEluYy4xHjAcBgkqhkiG9w0BCQEWD2FkbWluQGNpZW5hLmNvbTEmMCQGA1UEAxMd
1625RXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzExMTg1MzM2WhcN
1626MTcwMzA2MTg1MzM2WjBnMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNV
1627BAoTCkNpZW5hIEluYy4xFzAVBgNVBAMUDnVzZXJAY2llbmEuY29tMR0wGwYJKoZI
1628hvcNAQkBFg51c2VyQGNpZW5hLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
1629AQoCggEBAOxemcBsPn9tZsCa5o2JA6sQDC7A6JgCNXXl2VFzKLNNvB9PS6D7ZBsQ
16305An0zEDMNzi51q7lnrYg1XyiE4S8FzMGAFr94RlGMQJUbRD9V/oqszMX4k++iAOK
1631tIA1gr3x7Zi+0tkjVSVzXTmgNnhChAamdMsjYUG5+CY9WAicXyy+VEV3zTphZZDR
1632OjcjEp4m/TSXVPYPgYDXI40YZKX5BdvqykWtT/tIgZb48RS1NPyN/XkCYzl3bv21
1633qx7Mc0fcEbsJBIIRYTUkfxnsilcnmLxSYO+p+DZ9uBLBzcQt+4Rd5pLSfi21WM39
16342Z2oOi3vs/OYAPAqgmi2JWOv3mePa/8CAwEAAaNPME0wEwYDVR0lBAwwCgYIKwYB
1635BQUHAwIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL3d3dy5leGFtcGxlLmNvbS9l
1636eGFtcGxlX2NhLmNybDANBgkqhkiG9w0BAQUFAAOCAQEALBzMPDTIB6sLyPl0T6JV
1637MjOkyldAVhXWiQsTjaGQGJUUe1cmUJyZbUZEc13MygXMPOM4x7z6VpXGuq1c/Vxn
1638VzQ2fNnbJcIAHi/7G8W5/SQfPesIVDsHTEc4ZspPi5jlS/MVX3HOC+BDbOjdbwqP
1639RX0JEr+uOyhjO+lRxG8ilMRACoBUbw1eDuVDoEBgErSUC44pq5ioDw2xelc+Y6hQ
1640dmtYwfY0DbvwxHtA495frLyPcastDiT/zre7NL51MyUDPjjYjghNQEwvu66IKbQ3
1641T1tJBrgI7/WI+dqhKBFolKGKTDWIHsZXQvZ1snGu/FRYzg1l+R/jT8cRB9BDwhUt
1642yg==
1643-----END CERTIFICATE-----'''
1644 @classmethod
1645 def load_device_id(cls):
1646 '''Configure the device id'''
1647 did = OnosCtrl.get_device_id()
1648 #Set the default config
1649 cls.device_id = did
1650 cls.device_dict = { "devices" : {
1651 "{}".format(did) : {
1652 "basic" : {
1653 "driver" : "pmc-olt"
1654 }
1655 }
1656 },
1657 }
1658 return did
1659
1660 @classmethod
1661 def setUpClass(cls):
1662 '''Load the OLT config and activate relevant apps'''
1663 did = cls.load_device_id()
1664 network_cfg = { "devices" : {
1665 "{}".format(did) : {
1666 "basic" : {
1667 "driver" : "pmc-olt"
1668 }
1669 }
1670 },
1671 }
1672 ## Restart ONOS with cpqd driver config for OVS
1673 print('onos restart in setUpClass')
1674 cls.start_onos(network_cfg = network_cfg)
1675 #status, code = OnosCtrl.config(network_cfg)
1676 #if status is False:
1677 # log.info('JSON config request for app %s returned status %d' %(app, code))
1678 #assert_equal(status, True)
1679 #time.sleep(2)
1680 cls.install_app_table()
1681 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
1682 OnosCtrl.cord_olt_config(cls.olt.olt_device_data())
1683 cls.port_map, cls.port_list = cls.olt.olt_port_map()
1684 cls.activate_apps(cls.apps + cls.olt_apps)
1685
1686 @classmethod
1687 def tearDownClass(cls):
1688 '''Deactivate the olt apps and restart OVS back'''
1689 apps = cls.olt_apps + ( cls.table_app,)
1690 for app in apps:
1691 onos_ctrl = OnosCtrl(app)
1692 onos_ctrl.deactivate()
1693 cls.uninstall_app_table()
1694 #cls.start_onos(network_cfg = {})
1695
1696 @classmethod
1697 def activate_apps(cls, apps):
1698 for app in apps:
1699 onos_ctrl = OnosCtrl(app)
1700 status, _ = onos_ctrl.activate()
1701 assert_equal(status, True)
1702 time.sleep(2)
1703 @classmethod
1704 def install_app_table(cls):
1705 ##Uninstall the existing app if any
1706 OnosCtrl.uninstall_app(cls.table_app)
1707 time.sleep(2)
1708 log.info('Installing the multi table app %s for subscriber test' %(cls.table_app_file))
1709 OnosCtrl.install_app(cls.table_app_file)
1710 time.sleep(3)
1711 #onos_ctrl = OnosCtrl(cls.vtn_app)
1712 #onos_ctrl.deactivate()
1713
1714 @classmethod
1715 def uninstall_app_table(cls):
1716 ##Uninstall the table app on class exit
1717 OnosCtrl.uninstall_app(cls.table_app)
1718 time.sleep(2)
1719 log.info('Installing back the cord igmp app %s for subscriber test on exit' %(cls.app_file))
1720 OnosCtrl.install_app(cls.app_file)
1721 #onos_ctrl = OnosCtrl(cls.vtn_app)
1722 #onos_ctrl.activate()
1723
1724 @classmethod
1725 def start_onos(cls, network_cfg = None):
1726 if cls.onos_restartable is False:
1727 log.info('ONOS restart is disabled. Skipping ONOS restart')
1728 return
1729 if network_cfg is None:
1730 network_cfg = cls.device_dict
1731
1732 if type(network_cfg) is tuple:
1733 res = []
1734 for v in network_cfg:
1735 res += v.items()
1736 config = dict(res)
1737 else:
1738 config = network_cfg
1739 log.info('Restarting ONOS with new network configuration')
1740 return cord_test_onos_restart(config = config)
1741
1742 @classmethod
1743 def remove_onos_config(cls):
1744 try:
1745 os.unlink('{}/network-cfg.json'.format(cls.onos_config_path))
1746 except: pass
1747 @classmethod
1748 def start_cpqd(cls, mac = '00:11:22:33:44:55'):
1749 dpid = mac.replace(':', '')
1750 cpqd_file = os.sep.join( (cls.cpqd_path, 'cpqd.sh') )
1751 cpqd_cmd = '{} {}'.format(cpqd_file, dpid)
1752 ret = os.system(cpqd_cmd)
1753 assert_equal(ret, 0)
1754 time.sleep(10)
1755 device_id = 'of:{}{}'.format('0'*4, dpid)
1756 return device_id
1757
1758 @classmethod
1759 def start_ovs(cls):
1760 ovs_file = os.sep.join( (cls.ovs_path, 'of-bridge.sh') )
1761 ret = os.system(ovs_file)
1762 assert_equal(ret, 0)
1763 time.sleep(30)
1764
1765 @classmethod
1766 def ovs_cleanup(cls):
1767 ##For every test case, delete all the OVS groups
1768 cmd = 'ovs-ofctl del-groups br-int -OOpenFlow11 >/dev/null 2>&1'
1769 cord_test_shell(cmd)
1770 ##Since olt config is used for this test, we just fire a careless local cmd as well
1771 try:
1772 os.system(cmd)
1773 except: pass
1774
1775 def onos_aaa_load(self):
1776 if self.aaa_loaded:
1777 return
1778 aaa_dict = {'apps' : { 'org.onosproject.aaa' : { 'AAA' : { 'radiusSecret': 'radius_password',
1779 'radiusIp': '172.17.0.2' } } } }
1780 radius_ip = os.getenv('ONOS_AAA_IP') or '172.17.0.2'
1781 aaa_dict['apps']['org.onosproject.aaa']['AAA']['radiusIp'] = radius_ip
1782 self.onos_load_config('org.onosproject.aaa', aaa_dict)
1783 self.aaa_loaded = True
1784
1785 def onos_dhcp_table_load(self, config = None):
1786 dhcp_dict = {'apps' : { 'org.onosproject.dhcp' : { 'dhcp' : copy.copy(self.dhcp_server_config) } } }
1787 dhcp_config = dhcp_dict['apps']['org.onosproject.dhcp']['dhcp']
1788 if config:
1789 for k in config.keys():
1790 if dhcp_config.has_key(k):
1791 dhcp_config[k] = config[k]
1792 self.onos_load_config('org.onosproject.dhcp', dhcp_dict)
1793
1794 def onos_load_config(self, app, config):
1795 status, code = OnosCtrl.config(config)
1796 if status is False:
1797 log.info('JSON config request for app %s returned status %d' %(app, code))
1798 assert_equal(status, True)
1799 time.sleep(2)
1800 def dhcp_sndrcv(self, dhcp, update_seed = False):
1801 cip, sip = dhcp.discover(update_seed = update_seed)
1802 assert_not_equal(cip, None)
1803 assert_not_equal(sip, None)
1804 log.info('Got dhcp client IP %s from server %s for mac %s' %
1805 (cip, sip, dhcp.get_mac(cip)[0]))
1806 return cip,sip
1807
1808 def dhcp_request(self, subscriber, seed_ip = '10.10.10.1', update_seed = False):
1809 config = {'startip':'10.10.10.20', 'endip':'10.10.10.200',
1810 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca:fe",
1811 'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
1812 self.onos_dhcp_table_load(config)
1813 dhcp = DHCPTest(seed_ip = seed_ip, iface = subscriber.iface)
1814 cip, sip = self.dhcp_sndrcv(dhcp, update_seed = update_seed)
1815 return cip, sip
1816
1817 def recv_channel_cb(self, pkt):
1818 ##First verify that we have received the packet for the joined instance
1819 chan = self.subscriber.caddr(pkt[IP].dst)
1820 assert_equal(chan in self.subscriber.join_map.keys(), True)
1821 recv_time = monotonic.monotonic() * 1000000
1822 join_time = self.subscriber.join_map[chan][self.subscriber.STATS_JOIN].start
1823 delta = recv_time - join_time
1824 self.subscriber.join_rx_stats.update(packets=1, t = delta, usecs = True)
1825 self.subscriber.channel_update(chan, self.subscriber.STATS_RX, 1, t = delta)
1826 log.debug('Packet received in %.3f usecs for group %s after join' %(delta, pkt[IP].dst))
1827 self.test_status = True
1828
1829 def traffic_verify(self, subscriber):
1830 if subscriber.has_service('TRAFFIC'):
1831 url = 'http://www.google.com'
1832 resp = requests.get(url)
1833 self.test_status = resp.ok
1834 if resp.ok == False:
1835 log.info('Subscriber %s failed get from url %s with status code %d'
1836 %(subscriber.name, url, resp.status_code))
1837 else:
1838 log.info('GET request from %s succeeded for subscriber %s'
1839 %(url, subscriber.name))
1840 return self.test_status
1841
1842 def tls_verify(self, subscriber):
1843 if subscriber.has_service('TLS'):
1844 time.sleep(2)
1845 tls = TLSAuthTest(intf = subscriber.rx_intf)
1846 log.info('Running subscriber %s tls auth test' %subscriber.name)
1847 tls.runTest()
1848 self.test_status = True
1849 return self.test_status
1850 else:
1851 self.test_status = True
1852 return self.test_status
1853 def dhcp_verify(self, subscriber):
1854 if subscriber.has_service('DHCP'):
1855 cip, sip = self.dhcp_request(subscriber, update_seed = True)
1856 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
1857 subscriber.src_list = [cip]
1858 self.test_status = True
1859 return self.test_status
1860 else:
1861 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
1862 self.test_status = True
1863 return self.test_status
1864
1865 def dhcp_jump_verify(self, subscriber):
1866 if subscriber.has_service('DHCP'):
1867 cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.200.1')
1868 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
1869 subscriber.src_list = [cip]
1870 self.test_status = True
1871 return self.test_status
1872 else:
1873 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
1874 self.test_status = True
1875 return self.test_status
1876
1877 def dhcp_next_verify(self, subscriber):
1878 if subscriber.has_service('DHCP'):
1879 cip, sip = self.dhcp_request(subscriber, seed_ip = '10.10.150.1')
1880 log.info('Subscriber %s got client ip %s from server %s' %(subscriber.name, cip, sip))
1881 subscriber.src_list = [cip]
1882 self.test_status = True
1883 return self.test_status
1884 else:
1885 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
1886 self.test_status = True
1887 return self.test_status
1888 def igmp_verify(self, subscriber):
1889 chan = 0
1890 if subscriber.has_service('IGMP'):
1891 ##We wait for all the subscribers to join before triggering leaves
1892 if subscriber.rx_port > 1:
1893 time.sleep(5)
1894 subscriber.channel_join(chan, delay = 0)
1895 self.num_joins += 1
1896 while self.num_joins < self.num_subscribers:
1897 time.sleep(5)
1898 log.info('All subscribers have joined the channel')
1899 for i in range(10):
1900 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 10)
1901 log.info('Leaving channel %d for subscriber %s' %(chan, subscriber.name))
1902 subscriber.channel_leave(chan)
1903 time.sleep(5)
1904 log.info('Interface %s Join RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name,subscriber.join_rx_stats))
1905 #Should not receive packets for this subscriber
1906 self.recv_timeout = True
1907 subscriber.recv_timeout = True
1908 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 10)
1909 subscriber.recv_timeout = False
1910 self.recv_timeout = False
1911 log.info('Joining channel %d for subscriber %s' %(chan, subscriber.name))
1912 subscriber.channel_join(chan, delay = 0)
1913 self.test_status = True
1914 return self.test_status
1915
1916 def igmp_jump_verify(self, subscriber):
1917 if subscriber.has_service('IGMP'):
1918 for i in xrange(subscriber.num):
1919 log.info('Subscriber %s jumping channel' %subscriber.name)
1920 chan = subscriber.channel_jump(delay=0)
1921 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count = 1)
1922 log.info('Verified receive for channel %d, subscriber %s' %(chan, subscriber.name))
1923 time.sleep(3)
1924 log.info('Interface %s Jump RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name, subscriber.join_rx_stats))
1925 self.test_status = True
1926 return self.test_status
1927 def igmp_next_verify(self, subscriber):
1928 if subscriber.has_service('IGMP'):
1929 for i in xrange(subscriber.num):
1930 if i:
1931 chan = subscriber.channel_join_next(delay=0)
1932 else:
1933 chan = subscriber.channel_join(i, delay=0)
1934 log.info('Joined next channel %d for subscriber %s' %(chan, subscriber.name))
1935 subscriber.channel_receive(chan, cb = subscriber.recv_channel_cb, count=1)
1936 log.info('Verified receive for channel %d, subscriber %s' %(chan, subscriber.name))
1937 time.sleep(3)
1938 log.info('Interface %s Join Next RX stats for subscriber %s, %s' %(subscriber.iface, subscriber.name, subscriber.join_rx_stats))
1939 self.test_status = True
1940 return self.test_status
1941
1942 def generate_port_list(self, subscribers, channels):
1943 return self.port_list[:subscribers]
1944
1945 def subscriber_load(self, create = True, num = 10, num_channels = 1, channel_start = 0, port_list = []):
1946 '''Load the subscriber from the database'''
1947 self.subscriber_db = SubscriberDB(create = create, services = self.test_services)
1948 if create is True:
1949 self.subscriber_db.generate(num)
1950 self.subscriber_info = self.subscriber_db.read(num)
1951 self.subscriber_list = []
1952 if not port_list:
1953 port_list = self.generate_port_list(num, num_channels)
1954
1955 index = 0
1956 for info in self.subscriber_info:
1957 self.subscriber_list.append(Subscriber(name=info['Name'],
1958 service=info['Service'],
1959 port_map = self.port_map,
1960 num=num_channels,
1961 channel_start = channel_start,
1962 tx_port = port_list[index][0],
1963 rx_port = port_list[index][1]))
1964 if num_channels > 1:
1965 channel_start += num_channels
1966 index += 1
1967
1968 #load the ssm list for all subscriber channels
1969 igmpChannel = IgmpChannel()
1970 ssm_groups = map(lambda sub: sub.channels, self.subscriber_list)
1971 ssm_list = reduce(lambda ssm1, ssm2: ssm1+ssm2, ssm_groups)
1972 igmpChannel.igmp_load_ssm_config(ssm_list)
1973 def subscriber_join_verify( self, num_subscribers = 10, num_channels = 1,
1974 channel_start = 0, cbs = None, port_list = [], negative_subscriber_auth = None):
1975 self.test_status = False
1976 self.ovs_cleanup()
1977 subscribers_count = num_subscribers
1978 sub_loop_count = num_subscribers
1979 self.subscriber_load(create = True, num = num_subscribers,
1980 num_channels = num_channels, channel_start = channel_start, port_list = port_list)
1981 self.onos_aaa_load()
1982 self.thread_pool = ThreadPool(min(100, subscribers_count), queue_size=1, wait_timeout=1)
1983
1984 chan_leave = False #for single channel, multiple subscribers
1985 if None in (cbs, negative_subscriber_auth):
1986 cbs = (self.tls_verify, self.dhcp_verify, self.igmp_verify, self.traffic_verify)
1987 chan_leave = True
1988 cbs_negative = cbs
1989 for subscriber in self.subscriber_list:
1990 subscriber.start()
1991 if negative_subscriber_auth is 'half' and sub_loop_count%2 is not 0:
1992 cbs = (self.tls_verify, self.dhcp_verify, self.igmp_verify, self.traffic_verify)
1993 elif negative_subscriber_auth is 'onethird' and sub_loop_count%3 is not 0:
1994 cbs = (self.tls_verify, self.dhcp_verify, self.igmp_verify, self.traffic_verify)
1995 else:
1996 cbs = cbs_negative
1997 sub_loop_count = sub_loop_count - 1
1998 pool_object = subscriber_pool(subscriber, cbs)
1999 self.thread_pool.addTask(pool_object.pool_cb)
2000 self.thread_pool.cleanUpThreads()
2001 for subscriber in self.subscriber_list:
2002 subscriber.stop()
2003 if chan_leave is True:
2004 subscriber.channel_leave(0)
2005 subscribers_count = 0
2006 return self.test_status
2007 def tls_invalid_cert(self, subscriber):
2008 if subscriber.has_service('TLS'):
2009 time.sleep(2)
2010 log.info('Running subscriber %s tls auth test' %subscriber.name)
2011 tls = TLSAuthTest(client_cert = self.CLIENT_CERT_INVALID)
2012 tls.runTest()
2013 if tls.failTest == True:
2014 self.test_status = False
2015 return self.test_status
2016 else:
2017 self.test_status = True
2018 return self.test_status
2019
2020 def tls_no_cert(self, subscriber):
2021 if subscriber.has_service('TLS'):
2022 time.sleep(2)
2023 log.info('Running subscriber %s tls auth test' %subscriber.name)
2024 tls = TLSAuthTest(client_cert = '')
2025 tls.runTest()
2026 if tls.failTest == True:
2027 self.test_status = False
2028 return self.test_status
2029 else:
2030 self.test_status = True
2031 return self.test_status
2032
2033 def tls_self_signed_cert(self, subscriber):
2034 if subscriber.has_service('TLS'):
2035 time.sleep(2)
2036 log.info('Running subscriber %s tls auth test' %subscriber.name)
2037 tls = TLSAuthTest(client_cert = self.CLIENT_CERT)
2038 tls.runTest()
2039 if tls.failTest == False:
2040 self.test_status = True
2041 return self.test_status
2042 else:
2043 self.test_status = True
2044 return self.test_status
2045
2046 def tls_non_ca_authrized_cert(self, subscriber):
2047 if subscriber.has_service('TLS'):
2048 time.sleep(2)
2049 log.info('Running subscriber %s tls auth test' %subscriber.name)
2050 tls = TLSAuthTest(client_cert = self.CLIENT_CERT_NON_CA_AUTHORIZED)
2051 tls.runTest()
2052 if tls.failTest == False:
2053 self.test_status = True
2054 return self.test_status
2055 else:
2056 self.test_status = True
2057 return self.test_status
2058 def tls_Nsubscribers_use_same_valid_cert(self, subscriber):
2059 if subscriber.has_service('TLS'):
2060 time.sleep(2)
2061 log.info('Running subscriber %s tls auth test' %subscriber.name)
2062 num_users = 3
2063 for i in xrange(num_users):
2064 tls = TLSAuthTest(intf = 'veth{}'.format(i*2))
2065 tls.runTest()
2066 if tls.failTest == False:
2067 self.test_status = True
2068 return self.test_status
2069 else:
2070 self.test_status = True
2071 return self.test_status
2072
2073 def dhcp_discover_scenario(self, subscriber):
2074 if subscriber.has_service('DHCP'):
2075 time.sleep(2)
2076 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2077 t1 = self.subscriber_dhcp_1release()
2078 self.test_status = True
2079 return self.test_status
2080 else:
2081 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2082 self.test_status = True
2083 return self.test_status
2084
2085 def subscriber_dhcp_1release(self, iface = INTF_RX_DEFAULT):
2086 config = {'startip':'10.10.100.20', 'endip':'10.10.100.21',
2087 'ip':'10.10.100.2', 'mac': "ca:fe:ca:fe:8a:fe",
2088 'subnet': '255.255.255.0', 'broadcast':'10.10.100.255', 'router':'10.10.100.1'}
2089 self.onos_dhcp_table_load(config)
2090 self.dhcp = DHCPTest(seed_ip = '10.10.100.10', iface = iface)
2091 cip, sip = self.send_recv()
2092 log.info('Releasing ip %s to server %s' %(cip, sip))
2093 assert_equal(self.dhcp.release(cip), True)
2094 log.info('Triggering DHCP discover again after release')
2095 cip2, sip2 = self.send_recv(update_seed = True)
2096 log.info('Verifying released IP was given back on rediscover')
2097 assert_equal(cip, cip2)
2098 log.info('Test done. Releasing ip %s to server %s' %(cip2, sip2))
2099 assert_equal(self.dhcp.release(cip2), True)
2100 def dhcp_client_reboot_scenario(self, subscriber):
2101 if subscriber.has_service('DHCP'):
2102 time.sleep(2)
2103 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2104 tl = self.subscriber_dhcp_client_request_after_reboot()
2105 self.test_status = True
2106 return self.test_status
2107 else:
2108 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2109 self.test_status = True
2110 return self.test_status
2111
2112 def subscriber_dhcp_client_request_after_reboot(self, iface = INTF_RX_DEFAULT):
2113 #''' Client sends DHCP Request after reboot.'''
2114
2115 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2116 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2117 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2118 self.onos_dhcp_table_load(config)
2119 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
2120 cip, sip, mac, lval = self.dhcp.only_discover()
2121 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2122 (cip, sip, mac) )
2123
2124 log.info("Verifying Client 's IP and mac in DHCP Offer packet. Those should not be none, which is expected.")
2125
2126 if (cip == None and mac != None):
2127 log.info("Verified that Client 's IP and mac in DHCP Offer packet are none, which is not expected behavior.")
2128 assert_not_equal(cip, None)
2129
2130 else:
2131 new_cip, new_sip = self.dhcp.only_request(cip, mac)
2132 if new_cip == None:
2133 log.info("Got DHCP server NAK.")
2134 os.system('ifconfig '+iface+' down')
2135 log.info('Client goes down.')
2136 log.info('Delay for 5 seconds.')
2137
2138 time.sleep(5)
2139
2140 os.system('ifconfig '+iface+' up')
2141 log.info('Client is up now.')
2142
2143 new_cip, new_sip = self.dhcp.only_request(cip, mac)
2144 if new_cip == None:
2145 log.info("Got DHCP server NAK.")
2146 assert_not_equal(new_cip, None)
2147 elif new_cip != None:
2148 log.info("Got DHCP ACK.")
2149 def dhcp_client_renew_scenario(self, subscriber):
2150 if subscriber.has_service('DHCP'):
2151 time.sleep(2)
2152 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2153 tl = self.subscriber_dhcp_client_renew_time()
2154 self.test_status = True
2155 return self.test_status
2156 else:
2157 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2158 self.test_status = True
2159 return self.test_status
2160
2161 def subscriber_dhcp_client_renew_time(self, iface = INTF_RX_DEFAULT):
2162 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2163 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2164 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2165 self.onos_dhcp_table_load(config)
2166 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
2167 cip, sip, mac , lval = self.dhcp.only_discover()
2168 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2169 (cip, sip, mac) )
2170
2171 log.info("Verifying Client 's IP and mac in DHCP Offer packet. Those should not be none, which is expected.")
2172 if (cip == None and mac != None):
2173 log.info("Verified that Client 's IP and mac in DHCP Offer packet are none, which is not expected behavior.")
2174 assert_not_equal(cip, None)
2175 elif cip and sip and mac:
2176 log.info("Triggering DHCP Request.")
2177 new_cip, new_sip, lval = self.dhcp.only_request(cip, mac, renew_time = True)
2178 if new_cip and new_sip and lval:
2179 log.info("Client 's Renewal time is :%s",lval)
2180 log.info("Generating delay till renewal time.")
2181 time.sleep(lval)
2182 log.info("Client Sending Unicast DHCP request.")
2183 latest_cip, latest_sip = self.dhcp.only_request(new_cip, mac, unicast = True)
2184 if latest_cip and latest_sip:
2185 log.info("Got DHCP Ack. Lease Renewed for ip %s and mac %s from server %s." %
2186 (latest_cip, mac, latest_sip) )
2187
2188 elif latest_cip == None:
2189 log.info("Got DHCP NAK. Lease not renewed.")
2190 elif new_cip == None or new_sip == None or lval == None:
2191 log.info("Got DHCP NAK.")
2192 def dhcp_server_reboot_scenario(self, subscriber):
2193 if subscriber.has_service('DHCP'):
2194 time.sleep(2)
2195 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2196 tl = self.subscriber_dhcp_server_after_reboot()
2197 self.test_status = True
2198 return self.test_status
2199 else:
2200 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2201 self.test_status = True
2202 return self.test_status
2203 def subscriber_dhcp_server_after_reboot(self, iface = INTF_RX_DEFAULT):
2204 ''' DHCP server goes down.'''
2205 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2206 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2207 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2208 self.onos_dhcp_table_load(config)
2209 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
2210 cip, sip, mac, lval = self.dhcp.only_discover()
2211 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2212 (cip, sip, mac) )
2213 log.info("Verifying Client 's IP and mac in DHCP Offer packet. Those should not be none, which is expected.")
2214 if (cip == None and mac != None):
2215 log.info("Verified that Client 's IP and mac in DHCP Offer packet are none, which is not expected behavior.")
2216 assert_not_equal(cip, None)
2217 else:
2218 new_cip, new_sip = self.dhcp.only_request(cip, mac)
2219 if new_cip == None:
2220 log.info("Got DHCP server NAK.")
2221 assert_not_equal(new_cip, None)
2222 log.info('Getting DHCP server Down.')
2223 onos_ctrl = OnosCtrl(self.dhcp_app)
2224 onos_ctrl.deactivate()
2225 for i in range(0,4):
2226 log.info("Sending DHCP Request.")
2227 log.info('')
2228 new_cip, new_sip = self.dhcp.only_request(cip, mac)
2229 if new_cip == None and new_sip == None:
2230 log.info('')
2231 log.info("DHCP Request timed out.")
2232 elif new_cip and new_sip:
2233 log.info("Got Reply from DHCP server.")
2234 assert_equal(new_cip,None) #Neagtive Test Case
2235 log.info('Getting DHCP server Up.')
2236# self.activate_apps(self.dhcp_app)
2237 onos_ctrl = OnosCtrl(self.dhcp_app)
2238 status, _ = onos_ctrl.activate()
2239 assert_equal(status, True)
2240 time.sleep(3)
2241 for i in range(0,4):
2242 log.info("Sending DHCP Request after DHCP server is up.")
2243 log.info('')
2244 new_cip, new_sip = self.dhcp.only_request(cip, mac)
2245 if new_cip == None and new_sip == None:
2246 log.info('')
2247 log.info("DHCP Request timed out.")
2248 elif new_cip and new_sip:
2249 log.info("Got Reply from DHCP server.")
2250 assert_equal(new_cip,None) #Neagtive Test Case
2251 def dhcp_client_rebind_scenario(self, subscriber):
2252 if subscriber.has_service('DHCP'):
2253 time.sleep(2)
2254 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2255 tl = self.subscriber_dhcp_client_rebind_time()
2256 self.test_status = True
2257 return self.test_status
2258 else:
2259 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2260 self.test_status = True
2261 return self.test_status
2262
2263 def subscriber_dhcp_client_rebind_time(self, iface = INTF_RX_DEFAULT):
2264 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2265 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2266 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2267 self.onos_dhcp_table_load(config)
2268 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
2269 cip, sip, mac, lval = self.dhcp.only_discover()
2270 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2271 (cip, sip, mac) )
2272 log.info("Verifying Client 's IP and mac in DHCP Offer packet. Those should not be none, which is expected.")
2273 if (cip == None and mac != None):
2274 log.info("Verified that Client 's IP and mac in DHCP Offer packet are none, which is not expected behavior.")
2275 assert_not_equal(cip, None)
2276 elif cip and sip and mac:
2277 log.info("Triggering DHCP Request.")
2278 new_cip, new_sip, lval = self.dhcp.only_request(cip, mac, rebind_time = True)
2279 if new_cip and new_sip and lval:
2280 log.info("Client 's Rebind time is :%s",lval)
2281 log.info("Generating delay till rebind time.")
2282 time.sleep(lval)
2283 log.info("Client Sending broadcast DHCP requests for renewing lease or for getting new ip.")
2284 self.dhcp.after_T2 = True
2285 for i in range(0,4):
2286 latest_cip, latest_sip = self.dhcp.only_request(new_cip, mac)
2287 if latest_cip and latest_sip:
2288 log.info("Got DHCP Ack. Lease Renewed for ip %s and mac %s from server %s." %
2289 (latest_cip, mac, latest_sip) )
2290 break
2291 elif latest_cip == None:
2292 log.info("Got DHCP NAK. Lease not renewed.")
2293 assert_not_equal(latest_cip, None)
2294 elif new_cip == None or new_sip == None or lval == None:
2295 log.info("Got DHCP NAK.Lease not Renewed.")
2296 def dhcp_starvation_scenario(self, subscriber):
2297 if subscriber.has_service('DHCP'):
2298 time.sleep(2)
2299 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2300 tl = self.subscriber_dhcp_starvation()
2301 self.test_status = True
2302 return self.test_status
2303 else:
2304 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2305 self.test_status = True
2306 return self.test_status
2307
2308 def subscriber_dhcp_starvation(self, iface = INTF_RX_DEFAULT):
2309 '''DHCP starve'''
2310 config = {'startip':'182.17.0.20', 'endip':'182.17.0.69',
2311 'ip':'182.17.0.2', 'mac': "ca:fe:c3:fe:ca:fe",
2312 'subnet': '255.255.255.0', 'broadcast':'182.17.0.255', 'router':'182.17.0.1'}
2313 self.onos_dhcp_table_load(config)
2314 self.dhcp = DHCPTest(seed_ip = '182.17.0.1', iface = iface)
2315 log.info('Verifying 1 ')
2316 for x in xrange(50):
2317 mac = RandMAC()._fix()
2318 self.send_recv(mac = mac)
2319 log.info('Verifying 2 ')
2320 cip, sip = self.send_recv(update_seed = True, validate = False)
2321 assert_equal(cip, None)
2322 assert_equal(sip, None)
2323
2324 def dhcp_same_client_multi_discovers_scenario(self, subscriber):
2325 if subscriber.has_service('DHCP'):
2326 time.sleep(2)
2327 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2328 tl = self.subscriber_dhcp_same_client_multiple_discover()
2329 self.test_status = True
2330 return self.test_status
2331 else:
2332 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2333 self.test_status = True
2334 return self.test_status
2335 def subscriber_dhcp_same_client_multiple_discover(self, iface = INTF_RX_DEFAULT):
2336 ''' DHCP Client sending multiple discover . '''
2337 config = {'startip':'10.10.10.20', 'endip':'10.10.10.69',
2338 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca:fe",
2339 'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
2340 self.onos_dhcp_table_load(config)
2341 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
2342 cip, sip, mac, lval = self.dhcp.only_discover()
2343 log.info('Got dhcp client IP %s from server %s for mac %s . Not going to send DHCPREQUEST.' %
2344 (cip, sip, mac) )
2345 log.info('Triggering DHCP discover again.')
2346 new_cip, new_sip, new_mac , lval = self.dhcp.only_discover()
2347 if cip == new_cip:
2348 log.info('Got same ip for 2nd DHCP discover for client IP %s from server %s for mac %s. Triggering DHCP Request. '
2349 % (new_cip, new_sip, new_mac) )
2350 elif cip != new_cip:
2351 log.info('Ip after 1st discover %s' %cip)
2352 log.info('Map after 2nd discover %s' %new_cip)
2353 assert_equal(cip, new_cip)
2354
2355 def dhcp_same_client_multi_request_scenario(self, subscriber):
2356 if subscriber.has_service('DHCP'):
2357 time.sleep(2)
2358 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2359 tl = self.subscriber_dhcp_same_client_multiple_request()
2360 self.test_status = True
2361 return self.test_status
2362 else:
2363 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2364 self.test_status = True
2365 return self.test_status
2366 def subscriber_dhcp_same_client_multiple_request(self, iface = INTF_RX_DEFAULT):
2367 ''' DHCP Client sending multiple repeat DHCP requests. '''
2368 config = {'startip':'10.10.10.20', 'endip':'10.10.10.69',
2369 'ip':'10.10.10.2', 'mac': "ca:fe:ca:fe:ca:fe",
2370 'subnet': '255.255.255.0', 'broadcast':'10.10.10.255', 'router':'10.10.10.1'}
2371 self.onos_dhcp_table_load(config)
2372 self.dhcp = DHCPTest(seed_ip = '10.10.10.1', iface = iface)
2373 log.info('Sending DHCP discover and DHCP request.')
2374 cip, sip = self.send_recv()
2375 mac = self.dhcp.get_mac(cip)[0]
2376 log.info("Sending DHCP request again.")
2377 new_cip, new_sip = self.dhcp.only_request(cip, mac)
2378 if (new_cip,new_sip) == (cip,sip):
2379 log.info('Got same ip for 2nd DHCP Request for client IP %s from server %s for mac %s.'
2380 % (new_cip, new_sip, mac) )
2381 elif (new_cip,new_sip):
2382 log.info('No DHCP ACK')
2383 assert_equal(new_cip, None)
2384 assert_equal(new_sip, None)
2385 else:
2386 print "Something went wrong."
2387
2388 def dhcp_client_desired_ip_scenario(self, subscriber):
2389 if subscriber.has_service('DHCP'):
2390 time.sleep(2)
2391 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2392 tl = self.subscriber_dhcp_client_desired_address()
2393 self.test_status = True
2394 return self.test_status
2395 else:
2396 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2397 self.test_status = True
2398 return self.test_status
2399
2400 def subscriber_dhcp_client_desired_address(self, iface = INTF_RX_DEFAULT):
2401 '''DHCP Client asking for desired IP address.'''
2402 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2403 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2404 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2405 self.onos_dhcp_table_load(config)
2406 self.dhcp = DHCPTest(seed_ip = '20.20.20.31', iface = iface)
2407 cip, sip, mac , lval = self.dhcp.only_discover(desired = True)
2408 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2409 (cip, sip, mac) )
2410 if cip == self.dhcp.seed_ip:
2411 log.info('Got dhcp client IP %s from server %s for mac %s as desired .' %
2412 (cip, sip, mac) )
2413 elif cip != self.dhcp.seed_ip:
2414 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2415 (cip, sip, mac) )
2416 log.info('The desired ip was: %s .' % self.dhcp.seed_ip)
2417 assert_equal(cip, self.dhcp.seed_ip)
2418 def dhcp_client_request_pkt_with_non_offered_ip_scenario(self, subscriber):
2419 if subscriber.has_service('DHCP'):
2420 time.sleep(2)
2421 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2422 tl = self.subscriber_dhcp_server_nak_packet()
2423 self.test_status = True
2424 return self.test_status
2425 else:
2426 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2427 self.test_status = True
2428 return self.test_status
2429
2430 def subscriber_dhcp_server_nak_packet(self, iface = INTF_RX_DEFAULT):
2431 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2432 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2433 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2434 self.onos_dhcp_table_load(config)
2435 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
2436 cip, sip, mac, lval = self.dhcp.only_discover()
2437 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2438 (cip, sip, mac) )
2439 log.info("Verifying Client 's IP and mac in DHCP Offer packet. Those should not be none, which is expected.")
2440 if (cip == None and mac != None):
2441 log.info("Verified that Client 's IP and mac in DHCP Offer packet are none, which is not expected behavior.")
2442 assert_not_equal(cip, None)
2443 else:
2444 new_cip, new_sip = self.dhcp.only_request('20.20.20.31', mac)
2445 if new_cip == None:
2446 log.info("Got DHCP server NAK.")
2447 assert_equal(new_cip, None) #Negative Test Case
2448
2449 def dhcp_client_requested_out_pool_ip_scenario(self, subscriber):
2450 if subscriber.has_service('DHCP'):
2451 time.sleep(2)
2452 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2453 tl = self.subscriber_dhcp_client_desired_address_out_of_pool()
2454 self.test_status = True
2455 return self.test_status
2456 else:
2457 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2458 self.test_status = True
2459 return self.test_status
2460 def subscriber_dhcp_client_desired_address_out_of_pool(self, iface = INTF_RX_DEFAULT):
2461 '''DHCP Client asking for desired IP address from out of pool.'''
2462 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2463 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2464 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2465 self.onos_dhcp_table_load(config)
2466 self.dhcp = DHCPTest(seed_ip = '20.20.20.35', iface = iface)
2467 cip, sip, mac, lval = self.dhcp.only_discover(desired = True)
2468 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2469 (cip, sip, mac) )
2470 if cip == self.dhcp.seed_ip:
2471 log.info('Got dhcp client IP %s from server %s for mac %s as desired .' %
2472 (cip, sip, mac) )
2473 assert_equal(cip, self.dhcp.seed_ip) #Negative Test Case
2474
2475 elif cip != self.dhcp.seed_ip:
2476 log.info('Got dhcp client IP %s from server %s for mac %s .' %
2477 (cip, sip, mac) )
2478 log.info('The desired ip was: %s .' % self.dhcp.seed_ip)
2479 assert_not_equal(cip, self.dhcp.seed_ip)
2480
2481 elif cip == None:
2482 log.info('Got DHCP NAK')
2483
2484 def dhcp_client_specific_lease_scenario(self, subscriber):
2485 if subscriber.has_service('DHCP'):
2486 time.sleep(2)
2487 log.info('Running subscriber %s DHCP rediscover scenario test' %subscriber.name)
2488 tl = self.subscriber_dhcp_specific_lease_packet()
2489 self.test_status = True
2490 return self.test_status
2491 else:
2492 subscriber.src_list = ['10.10.10.{}'.format(subscriber.rx_port)]
2493 self.test_status = True
2494 return self.test_status
2495
2496 def subscriber_dhcp_specific_lease_packet(self, iface = INTF_RX_DEFAULT):
2497 ''' Client sends DHCP Discover packet for particular lease time.'''
2498 config = {'startip':'20.20.20.30', 'endip':'20.20.20.69',
2499 'ip':'20.20.20.2', 'mac': "ca:fe:ca:fe:ca:fe",
2500 'subnet': '255.255.255.0', 'broadcast':'20.20.20.255', 'router':'20.20.20.1'}
2501 self.onos_dhcp_table_load(config)
2502 self.dhcp = DHCPTest(seed_ip = '20.20.20.45', iface = iface)
2503 log.info('Sending DHCP discover with lease time of 700')
2504 cip, sip, mac, lval = self.dhcp.only_discover(lease_time = True)
2505
2506 log.info("Verifying Client 's IP and mac in DHCP Offer packet.")
2507 if (cip == None and mac != None):
2508 log.info("Verified that Client 's IP and mac in DHCP Offer packet are none, which is not expected behavior.")
2509 assert_not_equal(cip, None)
2510 elif lval != 700:
2511 log.info('Getting dhcp client IP %s from server %s for mac %s with lease time %s. That is not 700.' %
2512 (cip, sip, mac, lval) )
2513 assert_not_equal(lval, 700)
2514