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