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