blob: b65987bacca98b400e07c908cf253b34ad532b2e [file] [log] [blame]
Matteo Scandolo48d3d2d2017-08-08 13:05:27 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Chetan Gaonker26ae67e2017-07-18 19:58:30 +000017#
18# Copyright 2016-present Ciena Corporation
19#
20# Licensed under the Apache License, Version 2.0 (the "License");
21# you may not use this file except in compliance with the License.
22# You may obtain a copy of the License at
23#
24# http://www.apache.org/licenses/LICENSE-2.0
25#
26# Unless required by applicable law or agreed to in writing, software
27# distributed under the License is distributed on an "AS IS" BASIS,
28# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29# See the License for the specific language governing permissions and
30# limitations under the License.
31#
32from twisted.internet import defer
33from nose.tools import *
34from nose.twistedtools import reactor, deferred
35from scapy.all import *
36from select import select as socket_select
37import time, monotonic
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +000038import requests
Chetan Gaonker26ae67e2017-07-18 19:58:30 +000039import os
40import random
41import threading
42from IGMP import *
43from McastTraffic import *
44from Stats import Stats
45from OnosCtrl import OnosCtrl
46from OltConfig import OltConfig
47from Channels import IgmpChannel
48from CordLogger import CordLogger
49from CordTestConfig import setup_module, teardown_module
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +000050from onosclidriver import OnosCliDriver
51from CordTestUtils import get_mac, get_controller
52from portmaps import g_subscriber_port_map
Chetan Gaonker26ae67e2017-07-18 19:58:30 +000053from CordTestUtils import log_test
54log_test.setLevel('INFO')
55
56class IGMPProxyTestState:
57
58 def __init__(self, groups = [], df = None, state = 0):
59 self.df = df
60 self.state = state
61 self.counter = 0
62 self.groups = groups
63 self.group_map = {} ##create a send/recv count map
64 for g in groups:
65 self.group_map[g] = (Stats(), Stats())
66
67 def update(self, group, tx = 0, rx = 0, t = 0):
68 self.counter += 1
69 index = 0 if rx == 0 else 1
70 v = tx if rx == 0 else rx
71 if self.group_map.has_key(group):
72 self.group_map[group][index].update(packets = v, t = t)
73
74 def update_state(self):
75 self.state = self.state ^ 1
76
77class igmpproxy_exchange(CordLogger):
78
79 V_INF1 = 'veth0'
80 MGROUP1 = '239.1.2.3'
81 MGROUP2 = '239.2.2.3'
82 MINVALIDGROUP1 = '255.255.255.255'
83 MINVALIDGROUP2 = '239.255.255.255'
84 MMACGROUP1 = "01:00:5e:01:02:03"
85 MMACGROUP2 = "01:00:5e:02:02:03"
86 IGMP_DST_MAC = "01:00:5e:00:00:16"
87 IGMP_SRC_MAC = "5a:e1:ac:ec:4d:a1"
88 IP_SRC = '1.2.3.4'
89 IP_DST = '224.0.0.22'
90 NEGATIVE_TRAFFIC_STATUS = 1
91 igmp_eth = Ether(dst = IGMP_DST_MAC, type = ETH_P_IP)
92 igmp_ip = IP(dst = IP_DST)
93 IGMP_TEST_TIMEOUT = 5
94 IGMP_QUERY_TIMEOUT = 60
95 MCAST_TRAFFIC_TIMEOUT = 20
96 PORT_TX_DEFAULT = 2
97 PORT_RX_DEFAULT = 1
98 max_packets = 100
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +000099 MAX_PORTS = 100
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000100 proxy_app = 'org.opencord.igmpproxy'
101 mcast_app = 'org.opencord.mcast'
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000102 cord_config_app = 'org.opencord.config'
103 test_path = os.path.dirname(os.path.realpath(__file__))
104 proxy_device_id = OnosCtrl.get_device_id()
105 controller = get_controller()
106 app_files = [os.path.join(test_path, '..', 'apps/cord-config-3.0-SNAPSHOT.oar'), os.path.join(test_path, '..', 'apps/olt-app-3.0-SNAPSHOT.oar'), os.path.join(test_path, '..', 'apps/mcast-1.3.0-SNAPSHOT.oar'), os.path.join(test_path, '..', 'apps/onos-app-igmpproxy-1.1.0-SNAPSHOT.oar')]
107 proxy_config_file = os.path.join(test_path, '..', 'igmpproxy/igmpproxyconfig.json')
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000108 olt_conf_file = os.getenv('OLT_CONFIG_FILE', os.path.join(os.path.dirname(os.path.realpath(__file__)), '../setup/olt_config.json'))
109 ROVER_TEST_TIMEOUT = 300 #3600*86
110 ROVER_TIMEOUT = (ROVER_TEST_TIMEOUT - 100)
111 ROVER_JOIN_TIMEOUT = 60
112 VOLTHA_ENABLED = bool(int(os.getenv('VOLTHA_ENABLED', 0)))
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000113 configs = {}
114 proxy_interfaces_last = ()
115 interface_to_mac_map = {}
116 host_ip_map = {}
117 MAX_PORTS = 100
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000118
119 @classmethod
120 def setUpClass(cls):
121 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
122 cls.port_map, _ = cls.olt.olt_port_map()
123 if cls.VOLTHA_ENABLED is False:
124 OnosCtrl.config_device_driver()
125 OnosCtrl.cord_olt_config(cls.olt)
126 time.sleep(2)
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000127 cls.uninstall_cord_config_app()
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000128 time.sleep(2)
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000129 cls.install_igmpproxy()
130 cls.igmp_proxy_setup()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000131
132 @classmethod
133 def tearDownClass(cls):
134 if cls.VOLTHA_ENABLED is False:
135 OnosCtrl.config_device_driver(driver = 'ovs')
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000136 #cls.igmp_proxy_cleanup()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000137
138 def setUp(self):
139 ''' Activate the igmp proxy app'''
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000140 super(igmpproxy_exchange, self).setUp()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000141 self.igmp_channel = IgmpChannel()
142
143 def tearDown(self):
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000144 super(igmpproxy_exchange, self).tearDown()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000145
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000146 @classmethod
147 def uninstall_cord_config_app(cls):
148 log_test.info('Uninstalling org.opencord.config 1.2 version app')
149 OnosCtrl(cls.cord_config_app).deactivate()
150 OnosCtrl.uninstall_app(cls.cord_config_app, onos_ip = cls.controller)
151
152 @classmethod
153 def install_igmpproxy(cls):
154 for app in cls.app_files:
155 OnosCtrl.install_app(app, onos_ip = cls.controller)
156 OnosCtrl(app).activate()
157
158 @classmethod
159 def igmp_proxy_setup(cls):
160 did = OnosCtrl.get_device_id()
161 cls.proxy_device_id = did
162 cls.olt = OltConfig(olt_conf_file = cls.olt_conf_file)
163 cls.port_map, _ = cls.olt.olt_port_map()
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000164 #log_test.info('port map is %s'%cls.port_map)
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000165 if cls.port_map:
166 ##Per subscriber, we use 1 relay port
167 try:
168 proxy_port = cls.port_map[cls.port_map['relay_ports'][0]]
169 except:
170 proxy_port = cls.port_map['uplink']
171 cls.proxy_interface_port = proxy_port
172 cls.proxy_interfaces = (cls.port_map[cls.proxy_interface_port],)
173 else:
174 cls.proxy_interface_port = 100
175 cls.proxy_interfaces = (g_subscriber_port_map[cls.proxy_interface_port],)
176 cls.proxy_interfaces_last = cls.proxy_interfaces
177 if cls.port_map:
178 ##generate a ip/mac client virtual interface config for onos
179 interface_list = []
180 for port in cls.port_map['ports']:
181 port_num = cls.port_map[port]
182 if port_num == cls.port_map['uplink']:
183 continue
184 ip = cls.get_host_ip(port_num)
185 mac = cls.get_mac(port)
186 interface_list.append((port_num, ip, mac))
187
188 #configure igmp proxy virtual interface
189 proxy_ip = cls.get_host_ip(interface_list[0][0])
190 proxy_mac = cls.get_mac(cls.port_map[cls.proxy_interface_port])
191 interface_list.append((cls.proxy_interface_port, proxy_ip, proxy_mac))
192 cls.onos_interface_load(interface_list)
193
194 @classmethod
195 def igmp_proxy_cleanup(cls):
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000196 ##reset the ONOS port configuration back to default
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000197 for config in cls.configs.items():
198 OnosCtrl.delete(config)
199 # if cls.onos_restartable is True:
200 # log_test.info('Cleaning up dhcp relay config by restarting ONOS with default network cfg')
201 # return cord_test_onos_restart(config = {})
202
203 @classmethod
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000204 def onos_load_config(cls, config):
205 #log_test.info('onos load config is %s'%config)
206 status, code = OnosCtrl.config(config)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000207 if status is False:
208 log_test.info('JSON request returned status %d' %code)
209 assert_equal(status, True)
210 time.sleep(2)
211
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000212 @classmethod
213 def onos_interface_load(cls, interface_list):
214 interface_dict = { 'ports': {} }
215 for port_num, ip, mac in interface_list:
216 port_map = interface_dict['ports']
217 port = '{}/{}'.format(cls.proxy_device_id, port_num)
218 port_map[port] = { 'interfaces': [] }
219 interface_list = port_map[port]['interfaces']
220 interface_map = { 'ips' : [ '{}/{}'.format(ip, 24) ],
221 'mac' : mac,
222 'name': 'vir-{}'.format(port_num)
223 }
224 interface_list.append(interface_map)
225
226 #cls.onos_load_config(interface_dict)
227 cls.configs['interface_config'] = interface_dict
228
229 @classmethod
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000230 def onos_igmp_proxy_config_load(cls, FastLeave = "false"):
231 #cls.proxy_interface_port = 12
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000232 proxy_connect_point = '{}/{}'.format(cls.proxy_device_id, cls.proxy_interface_port)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000233 log_test.info('\nRelay interface port is %s'%cls.proxy_interface_port)
234 log_test.info('\nRelay interface is %s'%cls.port_map[cls.proxy_interface_port])
235 log_test.info('\nConnect point is %s'%proxy_connect_point)
236 cls.onos_load_config(cls.proxy_config_file,json_file=True)
237 igmpproxy_dict = { "apps": {
238 "org.onosproject.provider.lldp": {
239 "suppression": {
240 "deviceTypes": ["ROADM"],
241 "annotation": "{\"no-lldp\":null}"
242 }
243 },
244 "org.opencord.igmpproxy": {
245 "igmpproxy": {
246 "globalConnectPointMode": "true",
247 "globalConnectPoint": proxy_connect_point,
248 "UnsolicitedTimeOut": "2",
249 "MaxResp": "10",
250 "KeepAliveInterval": "120",
251 "KeepAliveCount": "3",
252 "LastQueryInterval": "2",
253 "LastQueryCount": "2",
254 "FastLeave": FastLeave,
255 "PeriodicQuery": "true",
256 "IgmpCos": "7",
257 "withRAUpLink": "true",
258 "withRADownLink": "true"
259 }
260 },
261 "org.opencord.mcast": {
262 "multicast": {
263 "ingressVlan": "222",
264 "egressVlan": "17"
265 }
266 }
267 }
268 }
269
270 """igmpproxy_dict = {'apps':{
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000271 'org.opencord.igmpproxy':{
272 'igmpproxy':
273 {'globalConnectPointMode': 'true',
274 'globalConnectPoint': proxy_connect_point,
275 'UnsolicitedTimeOut': '2',
276 'MaxResp': '10',
277 'KeepAliveInterval': '120',
278 'KeepAliveCount': '3',
279 'LastQueryInterval': '2',
280 'LastQueryCount': '2',
281 'FastLeave': 'false',
282 'PeriodicQuery': 'true',
283 'IgmpCos': '7',
284 'withRAUpLink': 'true',
285 'withRADownLink': 'true'
286 }
287 },
288 'org.opencord.mcast':{
289 'ingressVlan': '222',
290 'egressVlan': '17'
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000291 },
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000292 }
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000293 }"""
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000294 device_dict = {'devices':{
295 cls.proxy_device_id: {
296 'basic': {
297 'driver': 'default'
298 },
299 'accessDevice': {
300 'uplink': '2',
301 'vlan': '222',
302 'defaultVlan': '1'
303 }
304 }
305 }
306 }
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000307 log_test.info('Igmp proxy dict is %s'%igmpproxy_dict)
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000308 cls.onos_load_config(igmpproxy_dict)
309 cls.onos_load_config(device_dict)
310 cls.configs['relay_config'] = igmpproxy_dict
311 cls.configs['device_config'] = device_dict
312
313 @classmethod
314 def get_host_ip(cls, port):
315 if cls.host_ip_map.has_key(port):
316 return cls.host_ip_map[port]
317 cls.host_ip_map[port] = '192.168.1.{}'.format(port)
318 return cls.host_ip_map[port]
319
320 @classmethod
321 def host_load(cls, iface):
322 '''Have ONOS discover the hosts for dhcp-relay responses'''
323 port = g_subscriber_port_map[iface]
324 host = '173.17.1.{}'.format(port)
325 cmds = ( 'ifconfig {} 0'.format(iface),
326 'ifconfig {0} {1}'.format(iface, host),
327 'arping -I {0} {1} -c 2'.format(iface, host),)
328 #'ifconfig {} 0'.format(iface), )
329 for c in cmds:
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000330 log_test.info('Host load config command %s'%c)
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000331 os.system(c)
332
333 @classmethod
334 def host_config_load(cls, host_config = None):
335 for host in host_config:
336 status, code = OnosCtrl.host_config(host)
337 if status is False:
338 log_test.info('JSON request returned status %d' %code)
339 assert_equal(status, True)
340
341 @classmethod
342 def generate_host_config(cls,ip,mac):
343 num = 0
344 hosts_dict = {}
345 hosts_list = [(ip,mac),]
346 for host, mac in hosts_list:
347 port = num + 1 if num < cls.MAX_PORTS - 1 else cls.MAX_PORTS - 1
348 hosts_dict[host] = {'mac':mac, 'vlan':'none', 'ipAddresses':[host], 'location':{ 'elementId' : '{}'.format(cls.proxy_device_id), 'port': port}}
349 num += 1
350 return hosts_dict.values()
351
352
353 @classmethod
354 def get_mac(cls, iface):
355 if cls.interface_to_mac_map.has_key(iface):
356 return cls.interface_to_mac_map[iface]
357 mac = get_mac(iface, pad = 0)
358 cls.interface_to_mac_map[iface] = mac
359 return mac
360
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000361 def onos_ssm_table_load(self, groups, src_list = ['1.2.3.4'],flag = False):
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000362 ssm_dict = {'apps' : { 'org.opencord.igmpproxy' : { 'ssmTranslate' : [] } } }
363 ssm_xlate_list = ssm_dict['apps']['org.opencord.igmpproxy']['ssmTranslate']
364 if flag: #to maintain seperate group-source pair.
365 for i in range(len(groups)):
366 d = {}
367 d['source'] = src_list[i] or '0.0.0.0'
368 d['group'] = groups[i]
369 ssm_xlate_list.append(d)
370 else:
371 for g in groups:
372 for s in src_list:
373 d = {}
374 d['source'] = s or '0.0.0.0'
375 d['group'] = g
376 ssm_xlate_list.append(d)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000377 log_test.info('ONOS ssm table config dictionary is %s'%ssm_dict)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000378 self.onos_load_config(ssm_dict)
379 cord_port_map = {}
380 for g in groups:
381 cord_port_map[g] = (self.PORT_TX_DEFAULT, self.PORT_RX_DEFAULT)
382 self.igmp_channel.cord_port_table_load(cord_port_map)
383 time.sleep(2)
384
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000385 def random_mcast_ip(self,start_ip = '224.1.1.1', end_ip = '224.1.254.254'):
386 start = list(map(int, start_ip.split(".")))
387 end = list(map(int, end_ip.split(".")))
388 temp = start
389 ip_range = []
390 ip_range.append(start_ip)
391 while temp != end:
392 start[3] += 1
393 for i in (3, 2, 1):
394 if temp[i] == 255:
395 temp[i] = 0
396 temp[i-1] += 1
397 ip_range.append(".".join(map(str, temp)))
398 return random.choice(ip_range)
399
400 def randomsourceip(self,start_ip = '10.10.0.1', end_ip = '10.10.0.100'):
401 start = list(map(int, start_ip.split(".")))
402 end = list(map(int, end_ip.split(".")))
403 temp = start
404 ip_range = []
405 ip_range.append(start_ip)
406 while temp != end:
407 start[3] += 1
408 for i in (3, 2, 1):
409 if temp[i] == 255:
410 temp[i] = 0
411 temp[i-1] += 1
412 ip_range.append(".".join(map(str, temp)))
413 return random.choice(ip_range)
414
415
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000416 def get_igmp_intf(self):
417 inst = os.getenv('TEST_INSTANCE', None)
418 if not inst:
419 return 'veth0'
420 inst = int(inst) + 1
421 if inst >= self.port_map['uplink']:
422 inst += 1
423 if self.port_map.has_key(inst):
424 return self.port_map[inst]
425 return 'veth0'
426
427 def igmp_verify_join(self, igmpStateList):
428 sendState, recvState = igmpStateList
429 ## check if the send is received for the groups
430 for g in sendState.groups:
431 tx_stats = sendState.group_map[g][0]
432 tx = tx_stats.count
433 assert_greater(tx, 0)
434 rx_stats = recvState.group_map[g][1]
435 rx = rx_stats.count
436 assert_greater(rx, 0)
437 log_test.info('Receive stats %s for group %s' %(rx_stats, g))
438
439 log_test.info('IGMP test verification success')
440
441 def igmp_verify_leave(self, igmpStateList, leave_groups):
442 sendState, recvState = igmpStateList[0], igmpStateList[1]
443 ## check if the send is received for the groups
444 for g in sendState.groups:
445 tx_stats = sendState.group_map[g][0]
446 rx_stats = recvState.group_map[g][1]
447 tx = tx_stats.count
448 rx = rx_stats.count
449 assert_greater(tx, 0)
450 if g not in leave_groups:
451 log_test.info('Received %d packets for group %s' %(rx, g))
452 for g in leave_groups:
453 rx = recvState.group_map[g][1].count
454 assert_equal(rx, 0)
455
456 log_test.info('IGMP test verification success')
457
458 def mcast_traffic_timer(self):
459 log_test.info('MCAST traffic timer expiry')
460 self.mcastTraffic.stopReceives()
461
462 def send_mcast_cb(self, send_state):
463 for g in send_state.groups:
464 send_state.update(g, tx = 1)
465 return 0
466
467 ##Runs in the context of twisted reactor thread
468 def igmp_recv(self, igmpState):
469 s = socket_select([self.recv_socket], [], [], 1.0)
470 if self.recv_socket in s[0]:
471 p = self.recv_socket.recv()
472 try:
473 send_time = float(p.payload.load)
474 recv_time = monotonic.monotonic()
475 except:
476 log_test.info('Unexpected Payload received: %s' %p.payload.load)
477 return 0
478 #log_test.info( 'Recv in %.6f secs' %(recv_time - send_time))
479 igmpState.update(p.dst, rx = 1, t = recv_time - send_time)
480 return 0
481
482 def send_igmp_join(self, groups, src_list = ['1.2.3.4'], record_type=IGMP_V3_GR_TYPE_INCLUDE,
483 ip_pkt = None, iface = 'veth0', ssm_load = False, delay = 1):
484 if ssm_load is True:
485 self.onos_ssm_table_load(groups, src_list)
486 igmp = IGMPv3(type = IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30,
487 gaddr=self.IP_DST)
488 for g in groups:
489 gr = IGMPv3gr(rtype= record_type, mcaddr=g)
490 gr.sources = src_list
491 igmp.grps.append(gr)
492 if ip_pkt is None:
493 ip_pkt = self.igmp_eth/self.igmp_ip
494 pkt = ip_pkt/igmp
495 IGMPv3.fixup(pkt)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000496 #log_test.info('sending igmp join packet %s'%pkt.show())
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000497 sendp(pkt, iface=iface)
498 if delay != 0:
499 time.sleep(delay)
500
501 def send_igmp_join_recvQuery(self, groups, rec_queryCount = None, src_list = ['1.2.3.4'], ip_pkt = None, iface = 'veth0', delay = 2):
502 self.onos_ssm_table_load(groups, src_list)
503 igmp = IGMPv3(type = IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30,
504 gaddr=self.IP_DST)
505 for g in groups:
506 gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_INCLUDE, mcaddr=g)
507 gr.sources = src_list
508 gr.sources = src_list
509 igmp.grps.append(gr)
510 if ip_pkt is None:
511 ip_pkt = self.igmp_eth/self.igmp_ip
512 pkt = ip_pkt/igmp
513 IGMPv3.fixup(pkt)
514 if rec_queryCount == None:
515 log_test.info('Sending IGMP join for group %s and waiting for one query packet and printing the packet' %groups)
516 resp = srp1(pkt, iface=iface)
517 else:
518 log_test.info('Sending IGMP join for group %s and waiting for periodic query packets and printing one packet' %groups)
519 resp = srp1(pkt, iface=iface)
520# resp = srp1(pkt, iface=iface) if rec_queryCount else srp3(pkt, iface=iface)
521 resp[0].summary()
522 log_test.info('Sent IGMP join for group %s and received a query packet and printing packet' %groups)
523 if delay != 0:
524 time.sleep(delay)
525
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000526 def send_igmp_leave(self, groups, src_list = [], ip_pkt = None, iface = 'veth0', delay = 2):
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000527 log_test.info('entering into igmp leave function')
528 igmp = IGMPv3(type = IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30,
529 gaddr=self.IP_DST)
530 for g in groups:
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000531 #gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_EXCLUDE, mcaddr=g)
532 gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_CHANGE_TO_INCLUDE, mcaddr=g)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000533 gr.sources = src_list
534 igmp.grps.append(gr)
535 if ip_pkt is None:
536 ip_pkt = self.igmp_eth/self.igmp_ip
537 pkt = ip_pkt/igmp
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000538 log_test.info('igmp leave packet is %s'%pkt.show())
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000539 IGMPv3.fixup(pkt)
540 sendp(pkt, iface = iface)
541 if delay != 0:
542 time.sleep(delay)
543
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000544 def verify_igmp_packets_on_proxy_interface(self,ip_dst=None,iface=None,count=1,positive_test = True):
545 log_test.info('positive test variable inside verify_igmp_packets_on_proxy_interface function is %s'%positive_test)
546 if not iface:
547 iface = self.proxy_interfaces[0]
548 if not ip_dst:
549 ip_dst = self.IP_DST
550 self.status = False if positive_test is True else True
551 #log_test.info('self.status is %s'%self.status)
552 try:
553 def igmp_recv_cb(pkt):
554 log_test.info('igmp packet received on proxy interface %s'%pkt.show())
555 #log_test.info('igmp packet received on proxy interface %s'%pkt[Raw].show())
556 self.status = True if positive_test is True else False
557 sniff(prn = igmp_recv_cb,lfilter = lambda p: IP in p and p[IP].proto == 2 and p[IP].dst==ip_dst, count=count, timeout = 5, iface=iface)
558 log_test.info('self.status is %s'%self.status)
559 #assert_equal(self.status, True)
560 except Exception as error:
561 log_test.info('Got Unexpected error %s'%error)
562 raise
563 #assert_equal(self.status, True)
564
565 @deferred(30)
Anil Kumar Sankae08e4aa2017-09-08 22:23:48 +0000566 def test_igmpproxy_app_installation(self):
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000567 df = defer.Deferred()
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000568 def proxy_app_install(df):
569 self.uninstall_cord_config_app()
570 auth = ('karaf','karaf')
571 url = 'http://%s:8181/onos/v1/applications'.format(self.controller)
572 for file in self.app_files:
573 with open(file, 'rb') as payload:
574 res = requests.post(url,auth=auth,data=payload)
575 assert_equal(res.ok, True)
576 df.callback(0)
577 reactor.callLater(0, proxy_app_install, df)
578 return df
579
580 @deferred(30)
581 def test_igmpproxy_app_netcfg(self):
582 df = defer.Deferred()
583 def proxy_net_config(df):
584 auth = ('karaf','karaf')
585 net_cfg_url = 'http://172.17.0.2:8181/onos/v1/network/configuration/'.format(self.controller)
586 with open(self.proxy_config_file, 'rb') as payload:
587 res = requests.post(net_cfg_url,auth=auth,data=payload)
588 ssert_equal(res.ok, True)
589 df.callback(0)
590 reactor.callLater(0, proxy_net_config, df)
591 return df
592
593 @deferred(15)
594 def test_igmpproxy_for_first_join(self,iface='veth0'):
595 df = defer.Deferred()
596 def igmp_proxy_test(df):
597 group = [self.random_mcast_ip()]
598 src = [self.randomsourceip()]
599 self.onos_igmp_proxy_config_load()
600 self.onos_ssm_table_load(group,src_list=src)
601 try:
602 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
603 t.start()
604 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
605 iface = iface)
606 t.join()
607 assert_equal(self.status, True)
608 except Exception as error:
609 log_test.info('Igmp packet sent from subscriber interface, not received on proxy interface %s'%error)
610 raise
611 df.callback(0)
612 reactor.callLater(0, igmp_proxy_test, df)
613 return df
614
615 @deferred(20)
616 def test_igmpproxy_for_two_joins_with_different_igmp_groups(self,iface='veth0'):
617 df = defer.Deferred()
618 def igmp_proxy_test(df):
619 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
620 src = [self.randomsourceip()]
621 self.onos_igmp_proxy_config_load()
622 self.onos_ssm_table_load(groups,src_list=src)
623 for group in groups:
624 try:
625 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
626 t.start()
627 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
628 iface = iface)
629 t.join()
630 assert_equal(self.status, True)
631 except Exception as error:
632 log_test.info('Igmp packet sent from subscriber interface, not received on proxy interface %s'%error)
633 raise
634 df.callback(0)
635 reactor.callLater(0, igmp_proxy_test, df)
636 return df
637
638 @deferred(30)
639 def test_igmpproxy_for_igmp_join_with_proxy_app_deactivation(self, iface='veth0'):
640 df = defer.Deferred()
641 def igmp_proxy_test(df):
642 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
643 src = [self.randomsourceip()]
644 self.onos_igmp_proxy_config_load()
645 self.onos_ssm_table_load(groups,src_list=src)
646 try:
647 for group in groups:
648 positive_test = True if group is groups[0] else False
649 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface,kwargs = {'positive_test':positive_test})
650 t.start()
651 self.send_igmp_join(groups = [groups[0]], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
652 iface = iface)
653 t.join()
654 assert_equal(self.status, True)
655 OnosCtrl(self.proxy_app).deactivate()
656 time.sleep(1)
657 except Exception as error:
658 log_test.info('Igmp packet sent from subscriber interface, not received on proxy interface %s'%error)
659 raise
660 OnosCtrl(self.proxy_app).activate()
661 df.callback(0)
662 reactor.callLater(0, igmp_proxy_test, df)
663 return df
664
665 @deferred(30)
666 def test_igmpproxy_for_igmp_join_with_mcast_app_deactivation(self, iface='veth0'):
667 df = defer.Deferred()
668 def igmp_proxy_test(df):
669 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
670 src = [self.randomsourceip()]
671 self.onos_igmp_proxy_config_load()
672 self.onos_ssm_table_load(groups,src_list=src)
673 try:
674 for group in groups:
675 positive_test = True if group is groups[0] else False
676 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface,kwargs = {'positive_test':positive_test})
677 t.start()
678 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
679 iface = iface)
680 t.join()
681 assert_equal(self.status, True)
682 OnosCtrl(self.mcast_app).deactivate()
683 time.sleep(1)
684 except Exception as error:
685 log_test.info('Igmp packet sent from subscriber interface, not received on proxy interface %s'%error)
686 raise
687 OnosCtrl(self.mcast_app).activate()
688 df.callback(0)
689 reactor.callLater(0, igmp_proxy_test, df)
690 return df
691
692 @deferred(20)
693 def test_igmpproxy_for_igmp_joins_on_non_proxy_interface(self, iface='veth0', non_proxy_iface='veth4'):
694 df = defer.Deferred()
695 def igmp_proxy_test(df):
696 group = [self.random_mcast_ip()]
697 src = [self.randomsourceip()]
698 self.onos_igmp_proxy_config_load()
699 self.onos_ssm_table_load(group,src_list=src)
700 try:
701 t1 = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
702 t2 = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface,kwargs = {'iface':non_proxy_iface,'positive_test':False})
703 t1.start()
704 t2.start()
705 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
706 iface = iface)
707 t1.join()
708 assert_equal(self.status, True)
709 t2.join()
710 assert_equal(self.status, True)
711 except Exception as error:
712 log_test.info('Igmp packet sent from subscriber interface, not received on proxy interface %s'%error)
713 raise
714 df.callback(0)
715 reactor.callLater(0, igmp_proxy_test, df)
716 return df
717
718 @deferred(25)
719 def test_igmpproxy_sending_group_specific_query_receiving_igmp_leave(self, iface='veth0'):
720 df = defer.Deferred()
721 def igmp_proxy_test(df):
722 group = [self.random_mcast_ip()]
723 src = [self.randomsourceip()]
724 self.onos_igmp_proxy_config_load()
725 self.onos_ssm_table_load(group,src_list=src)
726 try:
727 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
728 iface = iface)
729 time.sleep(1)
730 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'ip_dst':group[0], 'iface':iface})
731 t.start()
732 self.send_igmp_leave(group, src_list= [], delay=10, iface = iface)
733 t.join()
734 assert_equal(self.status, True)
735 except Exception as error:
736 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
737 raise
738 df.callback(0)
739 reactor.callLater(0, igmp_proxy_test, df)
740 return df
741
742 @deferred(40)
743 def test_igmpproxy_verifying_group_specific_query_when_two_subscribers_leave_same_multicast_group_one_after_other(self,iface1='veth0',iface2='veth4'):
744 df = defer.Deferred()
745 def igmp_proxy_test(df):
746 group = [self.random_mcast_ip()]
747 src = [self.randomsourceip()]
748 self.onos_igmp_proxy_config_load()
749 self.onos_ssm_table_load(group,src_list=src)
750 try:
751 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
752 delay=1,iface = iface1)
753 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
754 delay=1,iface = iface2)
755 for iface in [iface1, iface2]:
756 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'ip_dst':group[0], 'iface':iface})
757 t.start()
758 time.sleep(1)
759 self.send_igmp_leave(group, src_list= [], delay=10, iface = iface)
760 t.join()
761 assert_equal(self.status, True)
762 except Exception as error:
763 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
764 raise
765 df.callback(0)
766 reactor.callLater(0, igmp_proxy_test, df)
767 return df
768
769 @deferred(60)
770 def test_igmpproxy_verifying_group_specific_query_sent_for_all_the_groups_after_subscriber_leaves(self, iface='veth0'):
771 df = defer.Deferred()
772 def igmp_proxy_test(df):
773 groups = [self.random_mcast_ip(),self.random_mcast_ip(), self.random_mcast_ip(), self.random_mcast_ip()]
774 src = [self.randomsourceip()]
775 self.onos_igmp_proxy_config_load()
776 self.onos_ssm_table_load(groups,src_list=src)
777 try:
778 self.send_igmp_join(groups = groups, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
779 delay=1,iface = iface)
780 threads = []
781 for group in groups:
782 threads.append(threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'ip_dst':group, 'iface':iface, 'count':len(groups)}))
783 for thread in threads:
784 thread.start()
785 time.sleep(1)
786 self.send_igmp_leave(groups, src_list= [], delay=11, iface = iface)
787 for thread in threads:
788 thread.join()
789 assert_equal(self.status, True)
790 except Exception as error:
791 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
792 raise
793 df.callback(0)
794 reactor.callLater(0, igmp_proxy_test, df)
795 return df
796
797 @deferred(25)
798 def test_igmpproxy_fast_leave(self, iface='veth0'):
799 df = defer.Deferred()
800 def igmp_proxy_test(df):
801 group = [self.random_mcast_ip()]
802 src = [self.randomsourceip()]
803 self.onos_igmp_proxy_config_load(FastLeave='true')
804 self.onos_ssm_table_load(group,src_list=src)
805 try:
806 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
807 iface = iface)
808 time.sleep(1)
809 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'positive_test':False, 'ip_dst':group[0], 'iface':iface})
810 t.start()
811 self.send_igmp_leave(group, src_list= [], delay=10, iface = iface)
812 t.join()
813 assert_equal(self.status, True)
814 except Exception as error:
815 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
816 raise
817 df.callback(0)
818 reactor.callLater(0, igmp_proxy_test, df)
819 return df
820
821 @deferred(30)
822 def test_igmpproxy_for_igmp_join_for_same_group_with_different_source(self, iface='veth0'):
823 df = defer.Deferred()
824 def igmp_proxy_test(df):
825 group = [self.random_mcast_ip()]
826 sources = [self.randomsourceip(),self.randomsourceip()]
827 self.onos_igmp_proxy_config_load()
828 self.onos_ssm_table_load(group,src_list=sources)
829 try:
830 for source in sources:
831 positive_test = True if source is sources[0] else False
832 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface,kwargs = {'positive_test':positive_test})
833 t.start()
834 self.send_igmp_join(groups = group, src_list = source, record_type = IGMP_V3_GR_TYPE_INCLUDE,
835 iface = iface)
836 t.join()
837 assert_equal(self.status, True)
838 time.sleep(1)
839 except:
840 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
841 raise
842 df.callback(0)
843 reactor.callLater(0, igmp_proxy_test, df)
844 return df
845
846 @deferred(20)
847 def test_igmpproxy_after_proxy_interface_toggles(self, iface='veth0'):
848 df = defer.Deferred()
849 def igmp_proxy_test(df):
850 group = self.random_mcast_ip()
851 group2 = self.random_mcast_ip()
852 src = [self.randomsourceip()]
853 self.onos_igmp_proxy_config_load()
854 self.onos_ssm_table_load([group,group2],src_list=src)
855 for toggle in ['Up','Down']:
856 if toggle == 'Down':
857 log_test.info('Toggling proxy interface ')
858 os.system('ifconfig {} down'.format(self.proxy_interfaces[0]))
859 time.sleep(1)
860 os.system('ifconfig {} up'.format(self.proxy_interfaces[0]))
861 time.sleep(1)
862 group = group2
863 try:
864 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
865 t.start()
866 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
867 iface = iface)
868 t.join()
869 assert_equal(self.status, True)
870 except:
871 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
872 raise
873 df.callback(0)
874 reactor.callLater(0, igmp_proxy_test, df)
875 return df
876
877 @deferred(20)
878 def test_igmpproxy_after_subscriber_interface_toggles(self,iface='veth0'):
879 df = defer.Deferred()
880 def igmp_proxy_test(df):
881 group = self.random_mcast_ip()
882 group2 = self.random_mcast_ip()
883 src = [self.randomsourceip()]
884 self.onos_igmp_proxy_config_load()
885 self.onos_ssm_table_load([group,group2],src_list=src)
886 for toggle in ['Up','Down']:
887 if toggle == 'Down':
888 log_test.info('Toggling subscriber interface ')
889 os.system('ifconfig {} down'.format(iface))
890 time.sleep(1)
891 os.system('ifconfig {} up'.format(iface))
892 time.sleep(1)
893 group = group2
894 try:
895 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
896 t.start()
897 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
898 iface = iface)
899 t.join()
900 assert_equal(self.status, True)
901 except:
902 log_test.info('Igmp query not received on subscriber interface in response to leave sent %s'%error)
903 raise
904 df.callback(0)
905 reactor.callLater(0, igmp_proxy_test, df)
906 return df
907
908 @deferred(20)
909 def test_igmpproxy_with_join_and_verify_traffic(self):
910 group = [self.random_mcast_ip()]
911 src = [self.randomsourceip()]
912 self.onos_igmp_proxy_config_load()
913 self.onos_ssm_table_load(group,src_list=src)
914 df = defer.Deferred()
915 igmpState = IGMPProxyTestState(groups = group, df = df)
916 igmpStateRecv = IGMPProxyTestState(groups = group, df = df)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000917 igmpStateList = (igmpState, igmpStateRecv)
918 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
919 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000920 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb, arg = igmpState)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000921 self.df = df
922 self.mcastTraffic = mcastTraffic
923 self.recv_socket = L3PacketSocket(iface = rx_intf, type = ETH_P_IP)
924
925 def igmp_srp_task(stateList):
926 igmpSendState, igmpRecvState = stateList
927 if not mcastTraffic.isRecvStopped():
928 self.igmp_recv(igmpRecvState)
929 reactor.callLater(0, igmp_srp_task, stateList)
930 else:
931 self.mcastTraffic.stop()
932 #log_test.info('Sending IGMP leave for groups: %s' %groups)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000933 self.send_igmp_leave(group , iface = rx_intf, delay = 2)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000934 self.recv_socket.close()
935 self.igmp_verify_join(stateList)
936 self.df.callback(0)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000937 self.send_igmp_join(group, iface = rx_intf)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +0000938 mcastTraffic.start()
939 self.test_timer = reactor.callLater(self.MCAST_TRAFFIC_TIMEOUT, self.mcast_traffic_timer)
940 reactor.callLater(0, igmp_srp_task, igmpStateList)
941 return df
942
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +0000943 @deferred(50)
944 def test_igmpproxy_with_two_subscribers_joining_same_igmp_group_verifying_traffic(self, iface1='veth0', iface2='veth4'):
945 df = defer.Deferred()
946 def igmp_proxy_test(df):
947 group = [self.random_mcast_ip()]
948 src = [self.randomsourceip()]
949 self.onos_igmp_proxy_config_load()
950 self.onos_ssm_table_load(group,src_list=src)
951 igmpState = IGMPProxyTestState(groups = group, df = df)
952 IGMPProxyTestState(groups = group, df = df)
953 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
954 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
955 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb,
956 arg = igmpState)
957 mcastTraffic.start()
958 time.sleep(1)
959 join_state = IGMPProxyTestState(groups = group)
960 try:
961 for iface in [iface1, iface2]:
962 positive_test = True if iface is iface1 else False
963 log_test.info('iface is %s'%iface)
964 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'positive_test':positive_test})
965 t.start()
966 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
967 iface = iface)
968 t.join()
969 assert_equal(self.status, True)
970 status = self.igmp_recv_task(iface, group, join_state)
971 except Exception as error:
972 log_test.info('Got some unexpected error %s'%error)
973 raise
974 mcastTraffic.stop()
975 df.callback(0)
976 reactor.callLater(0, igmp_proxy_test, df)
977 return df
978
979 @deferred(30)
980 def test_igmpproxy_with_two_subscribers_joining_different_igmp_group_verifying_traffic(self, iface1='veth0', iface2='veth4'):
981 df = defer.Deferred()
982 def igmp_proxy_test(df):
983 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
984 src = [self.randomsourceip()]
985 self.onos_igmp_proxy_config_load()
986 self.onos_ssm_table_load(groups,src_list=src)
987 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
988 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
989 try:
990 for group in groups:
991 igmpState = IGMPProxyTestState(groups = [group], df = df)
992 IGMPProxyTestState(groups = [group], df = df)
993 mcastTraffic = McastTraffic([group], iface= tx_intf, cb = self.send_mcast_cb,
994 arg = igmpState)
995 mcastTraffic.start()
996 time.sleep(1)
997 join_state = IGMPProxyTestState(groups = [group])
998 iface = iface1 if group is groups[0] else iface2
999 log_test.info('iface is %s and group is %s'%(iface,group))
1000 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1001 t.start()
1002 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
1003 iface = iface)
1004 t.join()
1005 assert_equal(self.status, True)
1006 status = self.igmp_recv_task(iface, [group], join_state)
1007 mcastTraffic.stop()
1008 except:
1009 log_test.info('Got some unexpected error %s'%error)
1010 raise
1011 df.callback(0)
1012 reactor.callLater(0, igmp_proxy_test, df)
1013 return df
1014
1015 @deferred(30)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001016 def test_igmpproxy_with_leave_and_verify_traffic(self):
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001017 group = [self.random_mcast_ip()]
1018 self.onos_igmp_proxy_config_load()
1019 self.onos_ssm_table_load(group)
1020 df = defer.Deferred()
1021 igmpState = IGMPProxyTestState(groups = group, df = df)
1022 IGMPProxyTestState(groups = group, df = df)
1023 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1024 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1025 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb,
1026 arg = igmpState)
1027 mcastTraffic.start()
1028 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1029 t.start()
1030 self.send_igmp_join(group, iface = rx_intf,delay=1)
1031 t.join()
1032 assert_equal(self.status, True)
1033 join_state = IGMPProxyTestState(groups = group)
1034 status = self.igmp_recv_task(rx_intf, group, join_state)
1035 self.send_igmp_leave(group, delay = 10, iface = rx_intf)
1036 join_state = IGMPProxyTestState(groups = group)
1037 status = self.igmp_not_recv_task(rx_intf, group, join_state)
1038 log_test.info('verified status for igmp recv task %s'%status)
1039 assert status == 1 , 'EXPECTED RESULT'
1040 df.callback(0)
1041 return df
1042
1043 @deferred(30)
1044 def test_igmpproxy_data_traffic_for_non_joined_group(self):
1045 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
1046 src = [self.randomsourceip()]
1047 self.onos_igmp_proxy_config_load()
1048 self.onos_ssm_table_load(groups,src_list=src)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001049 df = defer.Deferred()
1050 igmpState = IGMPProxyTestState(groups = groups, df = df)
1051 IGMPProxyTestState(groups = groups, df = df)
1052 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1053 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1054 mcastTraffic = McastTraffic(groups, iface= tx_intf, cb = self.send_mcast_cb,
1055 arg = igmpState)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001056 mcastTraffic.start()
1057 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1058 t.start()
1059 self.send_igmp_join([groups[0]],src_list= src, iface = rx_intf,delay=1)
1060 t.join()
1061 assert_equal(self.status, True)
1062 join_state = IGMPProxyTestState(groups = [groups[0]])
1063 status = self.igmp_recv_task(rx_intf, [groups[0]], join_state)
1064 join_state = IGMPProxyTestState(groups = [groups[1]])
1065 status = self.igmp_not_recv_task(rx_intf, [groups[1]], join_state)
1066 log_test.info('verified status for igmp recv task %s'%status)
1067 mcastTraffic.stop()
1068 assert status == 1 , 'EXPECTED RESULT'
1069 df.callback(0)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001070 return df
1071
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001072 #fail
1073 @deferred(timeout=60)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001074 def test_igmpproxy_with_leave_and_join_loop(self):
1075 self.groups = ['226.0.1.1', '227.0.0.1', '228.0.0.1', '229.0.0.1', '230.0.0.1' ]
1076 self.src_list = ['3.4.5.6', '7.8.9.10']
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001077 self.onos_igmp_proxy_config_load()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001078 self.onos_ssm_table_load(self.groups,src_list=self.src_list)
1079 df = defer.Deferred()
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001080 #self.df = df
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001081 self.iterations = 0
1082 self.num_groups = len(self.groups)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001083 self.MAX_TEST_ITERATIONS = 3
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001084 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001085 self.send_igmp_leave(self.groups,src_list = [], iface=rx_intf,delay=5)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001086
1087 def igmp_srp_task(v):
1088 if self.iterations < self.MAX_TEST_ITERATIONS:
1089 if v == 1:
1090 ##join test
1091 self.num_groups = random.randint(0, len(self.groups))
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001092 log_test.info('self.num_groups var is %s'%self.num_groups)
1093 try:
1094 for group in self.groups[:self.num_groups]:
1095 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1096 t.start()
1097 self.send_igmp_join(group,src_list = self.src_list,
1098 iface = rx_intf, delay = 1)
1099 t.join()
1100 assert_equal(self.status, True)
1101 except:
1102 log_test.info('Got some unexpected error %s'%error)
1103 raise
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001104 else:
1105 self.send_igmp_leave(self.groups[:self.num_groups],
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001106 src_list = [],
1107 iface = rx_intf, delay = 10)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001108 self.iterations += 1
1109 v ^= 1
1110 reactor.callLater(1.0 + 0.5*self.num_groups,
1111 igmp_srp_task, v)
1112 else:
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001113 df.callback(0)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001114 reactor.callLater(0, igmp_srp_task, 1)
1115 return df
1116
1117 def igmp_join_task(self, intf, groups, state, src_list = ['1.2.3.4']):
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001118 self.onos_ssm_table_load(groups, src_list)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001119 igmp = IGMPv3(type = IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30,
1120 gaddr=self.IP_DST)
1121 for g in groups:
1122 gr = IGMPv3gr(rtype = IGMP_V3_GR_TYPE_INCLUDE, mcaddr = g)
1123 gr.sources = src_list
1124 igmp.grps.append(gr)
1125
1126 for g in groups:
1127 state.group_map[g][0].update(1, t = monotonic.monotonic())
1128
1129 pkt = self.igmp_eth/self.igmp_ip/igmp
1130 IGMPv3.fixup(pkt)
1131 sendp(pkt, iface=intf)
1132 log_test.debug('Returning from join task')
1133
1134 def igmp_recv_task(self, intf, groups, join_state):
1135 recv_socket = L3PacketSocket(iface = intf, type = ETH_P_IP)
1136 group_map = {}
1137 for g in groups:
1138 group_map[g] = [0,0]
1139
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001140 log_test.info('Verifying join interface %s should receive multicast data'%intf)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001141 while True:
1142 p = recv_socket.recv()
1143 if p.dst in groups and group_map[p.dst][0] == 0:
1144 group_map[p.dst][0] += 1
1145 group_map[p.dst][1] = monotonic.monotonic()
1146 c = 0
1147 for g in groups:
1148 c += group_map[g][0]
1149 if c == len(groups):
1150 break
1151 for g in groups:
1152 join_start = join_state.group_map[g][0].start
1153 recv_time = group_map[g][1] * 1000000
1154 delta = (recv_time - join_start)
1155 log_test.info('Join for group %s received in %.3f usecs' %
1156 (g, delta))
1157
1158 recv_socket.close()
1159 log_test.debug('Returning from recv task')
1160
1161 def igmp_not_recv_task(self, intf, groups, join_state):
1162 log_test.info('Entering igmp not recv task loop')
1163 recv_socket = L2Socket(iface = intf, type = ETH_P_IP)
1164 group_map = {}
1165 for g in groups:
1166 group_map[g] = [0,0]
1167
1168 log_test.info('Verifying join interface, should not receive any multicast data')
1169 self.NEGATIVE_TRAFFIC_STATUS = 1
1170 def igmp_recv_cb(pkt):
1171 log_test.info('Multicast packet %s received for left groups %s' %(pkt[IP].dst, groups))
1172 self.NEGATIVE_TRAFFIC_STATUS = 2
1173 sniff(prn = igmp_recv_cb, count = 1, lfilter = lambda p: IP in p and p[IP].dst in groups,
1174 timeout = 3, opened_socket = recv_socket)
1175 recv_socket.close()
1176 return self.NEGATIVE_TRAFFIC_STATUS
1177
1178 def group_latency_check(self, groups):
1179 tasks = []
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001180 self.send_igmp_leave(groups = groups,delay=10)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001181 join_state = IGMPProxyTestState(groups = groups)
1182 tasks.append(threading.Thread(target=self.igmp_join_task, args = ('veth0', groups, join_state,)))
1183 traffic_state = IGMPProxyTestState(groups = groups)
1184 mcast_traffic = McastTraffic(groups, iface= 'veth2', cb = self.send_mcast_cb,
1185 arg = traffic_state)
1186 mcast_traffic.start()
1187 tasks.append(threading.Thread(target=self.igmp_recv_task, args = ('veth0', groups, join_state)))
1188 for t in tasks:
1189 t.start()
1190 for t in tasks:
1191 t.join()
1192
1193 mcast_traffic.stop()
1194 self.send_igmp_leave(groups = groups)
1195 return
1196
1197 @deferred(timeout=IGMP_QUERY_TIMEOUT + 10)
1198 def test_igmpproxy_with_1group_join_latency(self):
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001199 groups = [self.random_mcast_ip()]
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001200 df = defer.Deferred()
1201 def igmp_1group_join_latency():
1202 self.group_latency_check(groups)
1203 df.callback(0)
1204 reactor.callLater(0, igmp_1group_join_latency)
1205 return df
1206
1207 @deferred(timeout=IGMP_QUERY_TIMEOUT + 10)
1208 def test_igmpproxy_with_2group_join_latency(self):
1209 groups = [self.MGROUP1, self.MGROUP1]
1210 df = defer.Deferred()
1211 def igmp_2group_join_latency():
1212 self.group_latency_check(groups)
1213 df.callback(0)
1214 reactor.callLater(0, igmp_2group_join_latency)
1215 return df
1216
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001217 @deferred(timeout=IGMP_QUERY_TIMEOUT + 100)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001218 def test_igmpproxy_with_Ngroup_join_latency(self):
1219 groups = ['239.0.1.1', '240.0.1.1', '241.0.1.1', '242.0.1.1']
1220 df = defer.Deferred()
1221 def igmp_Ngroup_join_latency():
1222 self.group_latency_check(groups)
1223 df.callback(0)
1224 reactor.callLater(0, igmp_Ngroup_join_latency)
1225 return df
1226
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001227 @deferred(70)
1228 def test_igmpproxy_with_join_rover_all(self,iface='veth0'):
1229 self.onos_igmp_proxy_config_load()
1230 df = defer.Deferred()
1231 def igmp_proxy_join_rover():
1232 s = (224 << 16) | 1
1233 #e = (225 << 24) | (255 << 16) | (255 << 16) | 255
1234 e = (224 << 16) | 10
1235 for i in xrange(s, e+1):
1236 if i&0xff:
1237 ip = '%d.%d.%d.%d'%((i>>16)&0xff, (i>>16)&0xff, (i>>8)&0xff, i&0xff)
1238 try:
1239 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1240 t.start()
1241 self.send_igmp_join(groups = [ip], ssm_load=True, iface = iface, delay=1)
1242 t.join()
1243 except:
1244 raise
1245 df.callback(0)
1246 reactor.callLater(0, igmp_proxy_join_rover)
1247 return df
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001248
1249 @deferred(timeout=ROVER_TEST_TIMEOUT)
1250 def test_igmpproxy_with_join_rover(self):
1251 df = defer.Deferred()
1252 iface = self.get_igmp_intf()
1253 self.df = df
1254 self.count = 0
1255 self.timeout = 0
1256 self.complete = False
1257 def igmp_join_timer():
1258 self.timeout += self.ROVER_JOIN_TIMEOUT
1259 log_test.info('IGMP joins sent: %d' %self.count)
1260 if self.timeout >= self.ROVER_TIMEOUT:
1261 self.complete = True
1262 reactor.callLater(self.ROVER_JOIN_TIMEOUT, igmp_join_timer)
1263
1264 reactor.callLater(self.ROVER_JOIN_TIMEOUT, igmp_join_timer)
1265 self.start_channel = (224 << 24) | 1
1266 self.end_channel = (224 << 24) | 200 #(225 << 24) | (255 << 16) | (255 << 16) | 255
1267 self.current_channel = self.start_channel
1268 def igmp_join_rover(self):
1269 #e = (224 << 24) | 10
1270 chan = self.current_channel
1271 self.current_channel += 1
1272 if self.current_channel >= self.end_channel:
1273 chan = self.current_channel = self.start_channel
1274 if chan&0xff:
1275 ip = '%d.%d.%d.%d'%((chan>>24)&0xff, (chan>>16)&0xff, (chan>>8)&0xff, chan&0xff)
1276 self.send_igmp_join([ip], delay = 0, ssm_load = False, iface = iface)
1277 self.count += 1
1278 if self.complete == True:
1279 log_test.info('%d IGMP joins sent in %d seconds over %s' %(self.count, self.timeout, iface))
1280 self.df.callback(0)
1281 else:
1282 reactor.callLater(0, igmp_join_rover, self)
1283 reactor.callLater(0, igmp_join_rover, self)
1284 return df
1285
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001286 #fail
1287 @deferred(timeout=IGMP_QUERY_TIMEOUT + 30)
1288 def test_igmpproxy_sends_periodic_general_query_on_subscriber_connected_segment(self,iface='veth0'):
1289 groups = [self.random_mcast_ip()]
1290 self.onos_igmp_proxy_config_load()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001291 self.onos_ssm_table_load(groups)
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001292 self.send_igmp_join(groups)
1293 self.success = False
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001294 df = defer.Deferred()
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001295 def igmp_query_timeout():
1296 def igmp_query_cb(pkt):
1297 log_test.info('received igmp query packet is %s'%pkt.show())
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001298 self.success = True
1299 sniff(prn = igmp_query_cb, count=1, lfilter = lambda p: IP in p and p[IP].proto == 2 and p[IP].dst == '224.0.0.1',
1300 timeout = self.IGMP_QUERY_TIMEOUT+2, iface = iface)
1301 df.callback(0)
1302 self.send_igmp_join(groups)
1303 self.test_timer = reactor.callLater(0,igmp_query_timeout)
1304 assert_equal(self.success, True)
1305 return df
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001306
Anil Kumar Sanka2f8e7d72017-09-28 00:48:26 +00001307
1308 @deferred(timeout=IGMP_QUERY_TIMEOUT + 30)
1309 def test_igmpproxy_with_not_sending_periodic_general_query_on_proxy_connected_interface(self):
1310 groups = [self.random_mcast_ip()]
1311 self.onos_igmp_proxy_config_load()
1312 self.onos_ssm_table_load(groups)
1313 self.send_igmp_join(groups)
1314 self.success = False
1315 df = defer.Deferred()
1316 def igmp_query_timeout():
1317 def igmp_query_cb(pkt):
1318 log_test.info('received igmp query packet on proxy connected interface %s'%pkt.show())
1319 self.success = True
1320 sniff(prn = igmp_query_cb, count=1, lfilter = lambda p: IP in p and p[IP].proto == 2 and p[IP].dst == '224.0.0.1',
1321 timeout = self.IGMP_QUERY_TIMEOUT+2, iface = self.proxy_interfaces[0])
1322 df.callback(0)
1323 self.send_igmp_join(groups)
1324 self.test_timer = reactor.callLater(0,igmp_query_timeout)
1325 assert_equal(self.success, False)
1326 return df
1327
1328 @deferred(50)
1329 def test_igmpproxy_two_joins_one_leave_from_same_subscriber_and_verify_traffic(self,iface='veth0'):
1330 df = defer.Deferred()
1331 def igmp_proxy_test(df):
1332 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
1333 src = [self.randomsourceip()]
1334 self.onos_igmp_proxy_config_load()
1335 self.onos_ssm_table_load(groups,src_list=src)
1336 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1337 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1338 try:
1339 for group in groups:
1340 igmpState = IGMPProxyTestState(groups = [group], df = df)
1341 IGMPProxyTestState(groups = [group], df = df)
1342 mcastTraffic = McastTraffic([group], iface= tx_intf, cb = self.send_mcast_cb,
1343 arg = igmpState)
1344 mcastTraffic.start()
1345 time.sleep(1)
1346 join_state = IGMPProxyTestState(groups = [group])
1347 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1348 t.start()
1349 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
1350 iface = iface)
1351 t.join()
1352 assert_equal(self.status, True)
1353 status = self.igmp_recv_task(iface, [group], join_state)
1354 if group is groups[1]:
1355 log_test.info('sending leave for group %s'%group)
1356 self.send_igmp_leave([group], delay = 11, iface = iface)
1357 join_state = IGMPProxyTestState(groups = [group])
1358 status = self.igmp_not_recv_task(rx_intf, [group], join_state)
1359 log_test.info('verified status for igmp recv task %s'%status)
1360 assert status == 1 , 'EXPECTED RESULT'
1361 log_test.info('verifying subscriber receives igmp traffic for group %s'%groups[0])
1362 join_state = IGMPProxyTestState(groups = [groups[0]])
1363 status = self.igmp_recv_task(iface, [groups[0]], join_state)
1364 mcastTraffic.stop()
1365 except:
1366 log_test.info('Got some unexpected error %s'%error)
1367 raise
1368 df.callback(0)
1369 reactor.callLater(0, igmp_proxy_test, df)
1370 return df
1371
1372 #fail
1373 @deferred(50)
1374 def test_igmpproxy_two_subscribers_joins_igmp_group_one_subscriber_goes_down_and_verify_traffic(self,iface1='veth0',iface2='veth4'):
1375 df = defer.Deferred()
1376 def igmp_proxy_test(df):
1377 group = [self.random_mcast_ip()]
1378 src = [self.randomsourceip()]
1379 self.onos_igmp_proxy_config_load()
1380 self.onos_ssm_table_load(group,src_list=src)
1381 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1382 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1383 try:
1384 igmpState = IGMPProxyTestState(groups = group, df = df)
1385 IGMPProxyTestState(groups = group, df = df)
1386 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb,
1387 arg = igmpState)
1388 mcastTraffic.start()
1389 time.sleep(1)
1390 join_state = IGMPProxyTestState(groups = group)
1391 for iface in [iface1, iface2]:
1392 positive_test = True if iface is iface1 else False
1393 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'positive_test':positive_test})
1394 t.start()
1395 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
1396 iface = iface)
1397 t.join()
1398 assert_equal(self.status, True)
1399 status = self.igmp_recv_task(iface, group, join_state)
1400 if iface is iface2:
1401 log_test.info('bringning donw iface %s'%iface)
1402 os.system('ifconfig {} down'.format(iface))
1403 time.sleep(1)
1404 os.system('ifconfig {} up'.format(iface))
1405 time.sleep(1)
1406 status = self.igmp_not_recv_task(iface, group, join_state)
1407 log_test.info('verified status for igmp recv task %s'%status)
1408 assert status == 1 , 'EXPECTED RESULT'
1409 log_test.info('verifying subscriber %s receives igmp traffic'%iface1)
1410 status = self.igmp_recv_task(iface1, group, join_state)
1411 mcastTraffic.stop()
1412 except:
1413 log_test.info('Got some unexpected error %s'%error)
1414 raise
1415 df.callback(0)
1416 reactor.callLater(0, igmp_proxy_test, df)
1417 return df
1418
1419 @deferred(50)
1420 def test_igmpproxy_two_subscribers_join_different_igmp_groups_one_subscriber_leaves_and_verifying_traffic(self, iface1='veth0', iface2='veth4'):
1421 df = defer.Deferred()
1422 def igmp_proxy_test(df):
1423 groups = [self.random_mcast_ip(),self.random_mcast_ip()]
1424 src = [self.randomsourceip()]
1425 self.onos_igmp_proxy_config_load()
1426 self.onos_ssm_table_load(groups,src_list=src)
1427 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1428 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1429 try:
1430 for group in groups:
1431 igmpState = IGMPProxyTestState(groups = [group], df = df)
1432 IGMPProxyTestState(groups = [group], df = df)
1433 mcastTraffic = McastTraffic([group], iface= tx_intf, cb = self.send_mcast_cb,
1434 arg = igmpState)
1435 mcastTraffic.start()
1436 time.sleep(1)
1437 join_state = IGMPProxyTestState(groups = [group])
1438 iface = iface1 if group is groups[0] else iface2
1439 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1440 t.start()
1441 self.send_igmp_join(groups = [group], src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
1442 delay=1,iface = iface)
1443 t.join()
1444 assert_equal(self.status, True)
1445 status = self.igmp_recv_task(iface, [group], join_state)
1446 if group is groups[1]:
1447 log_test.info('sending leave for group %s'%group)
1448 time.sleep(3)
1449 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1450 t.start()
1451 self.send_igmp_leave([group], delay = 15, iface = iface)
1452 t.join()
1453 assert_equal(self.status, True)
1454 join_state = IGMPProxyTestState(groups = [group])
1455 status = self.igmp_not_recv_task(iface, [group], join_state)
1456 log_test.info('verified status for igmp recv task %s'%status)
1457 assert status == 1 , 'EXPECTED RESULT'
1458 log_test.info('verifying subscriber receives igmp traffic for group %s'%groups[0])
1459 join_state = IGMPProxyTestState(groups = [groups[0]])
1460 status = self.igmp_recv_task(iface1, [groups[0]], join_state)
1461 mcastTraffic.stop()
1462 except:
1463 log_test.info('Got some unexpected error %s'%error)
1464 raise
1465 df.callback(0)
1466 reactor.callLater(0, igmp_proxy_test, df)
1467 return df
1468
1469 @deferred(50)
1470 def test_igmpproxy_with_two_subscriber_joining_same_igmp_group_one_subscriber_doing_fast_leave_verifying_traffic(self, iface1='veth0', iface2='veth4'):
1471 df = defer.Deferred()
1472 def igmp_proxy_test(df):
1473 group = [self.random_mcast_ip()]
1474 src = [self.randomsourceip()]
1475 self.onos_igmp_proxy_config_load(FastLeave='true')
1476 self.onos_ssm_table_load(group,src_list=src)
1477 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1478 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1479 try:
1480 for iface in [iface1, iface2]:
1481 igmpState = IGMPProxyTestState(groups = group, df = df)
1482 IGMPProxyTestState(groups = group, df = df)
1483 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb,
1484 arg = igmpState)
1485 mcastTraffic.start()
1486 time.sleep(1)
1487 join_state = IGMPProxyTestState(groups = group)
1488 positive_test = True if iface is iface1 else False
1489 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface, kwargs = {'positive_test':positive_test})
1490 t.start()
1491 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
1492 delay=1,iface = iface)
1493 t.join()
1494 assert_equal(self.status, True)
1495 status = self.igmp_recv_task(iface, group, join_state)
1496 if iface is iface2:
1497 log_test.info('sending leave for group %s'%group)
1498 time.sleep(10)
1499 self.send_igmp_leave(group, delay = 1, iface = iface)
1500 join_state = IGMPProxyTestState(groups = group)
1501 status = self.igmp_not_recv_task(iface, group, join_state)
1502 log_test.info('verified status for igmp recv task %s'%status)
1503 assert status == 1 , 'EXPECTED RESULT'
1504 log_test.info('verifying subscriber receives igmp traffic for group %s'%group)
1505 join_state = IGMPProxyTestState(groups = group)
1506 status = self.igmp_recv_task(iface1, group, join_state)
1507 mcastTraffic.stop()
1508 except:
1509 log_test.info('Got some unexpected error %s'%error)
1510 raise
1511 df.callback(0)
1512 reactor.callLater(0, igmp_proxy_test, df)
1513 return df
1514
1515 #fail
1516 @deferred(20)
1517 def test_igmpproxy_with_multicast_source_connected_on_proxy_interface(self, iface='veth0'):
1518 df = defer.Deferred()
1519 def igmp_proxy_test(df):
1520 group = [self.random_mcast_ip()]
1521 src = [self.randomsourceip()]
1522 self.onos_igmp_proxy_config_load()
1523 self.onos_ssm_table_load(group,src_list=src)
1524 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1525 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1526 igmpState = IGMPProxyTestState(groups = group, df = df)
1527 IGMPProxyTestState(groups = group, df = df)
1528 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb,
1529 arg = igmpState)
1530 mcastTraffic.start()
1531 time.sleep(1)
1532 join_state = IGMPProxyTestState(groups = group)
1533 try:
1534 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1535 t.start()
1536 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_INCLUDE,
1537 delay=1,iface = iface)
1538 t.join()
1539 assert_equal(self.status, True)
1540 status = self.igmp_recv_task(iface, group, join_state)
1541 mcastTraffic.stop()
1542 except:
1543 log_test.info('Got some unexpected error %s'%error)
1544 raise
1545 df.callback(0)
1546 reactor.callLater(0, igmp_proxy_test, df)
1547 return df
1548
1549 #fail
1550 @deferred(20)
1551 def test_igmpproxy_which_drops_multicast_traffic_for_exclude_record_type_group(self, iface='veth0'):
1552 df = defer.Deferred()
1553 def igmp_proxy_test(df):
1554 group = [self.random_mcast_ip()]
1555 src = [self.randomsourceip()]
1556 self.onos_igmp_proxy_config_load()
1557 self.onos_ssm_table_load(group,src_list=src)
1558 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1559 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1560 try:
1561 igmpState = IGMPProxyTestState(groups = group, df = df)
1562 IGMPProxyTestState(groups = group, df = df)
1563 mcastTraffic = McastTraffic(group, iface= tx_intf, cb = self.send_mcast_cb,
1564 arg = igmpState)
1565 mcastTraffic.start()
1566 time.sleep(1)
1567 join_state = IGMPProxyTestState(groups = group)
1568 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1569 t.start()
1570 self.send_igmp_join(groups = group, src_list = src,record_type = IGMP_V3_GR_TYPE_EXCLUDE,
1571 iface = iface)
1572 t.join()
1573 assert_equal(self.status, True)
1574 status = self.igmp_not_recv_task(iface, group, join_state)
1575 log_test.info('verified status for igmp recv task %s'%status)
1576 assert status == 1 , 'EXPECTED RESULT'
1577 except:
1578 log_test.info('Got some unexpected error %s'%error)
1579 raise
1580 mcastTraffic.stop()
1581 df.callback(0)
1582 reactor.callLater(0, igmp_proxy_test, df)
1583 return df
1584
1585 #fail : exclude record type igmp join not forwarded to proxy interface
1586 @deferred(40)
1587 def test_igmpproxy_with_two_subscriber_joins_set_with_include_and_exclude_mode_record_types_verifying_traffic(self, iface1='veth0', iface2='veth4'):
1588 df = defer.Deferred()
1589 def igmp_proxy_test(df):
1590 groups = [self.random_mcast_ip(), self.random_mcast_ip()]
1591 src = [self.randomsourceip()]
1592 self.onos_igmp_proxy_config_load()
1593 self.onos_ssm_table_load(groups,src_list=src)
1594 tx_intf = self.port_map[self.PORT_TX_DEFAULT]
1595 rx_intf = self.port_map[self.PORT_RX_DEFAULT]
1596 try:
1597 for group in groups:
1598 iface = iface1 if group is groups[0] else iface2
1599 r_type = IGMP_V3_GR_TYPE_INCLUDE if group is groups[0] else IGMP_V3_GR_TYPE_EXCLUDE
1600 igmpState = IGMPProxyTestState(groups = [group], df = df)
1601 IGMPProxyTestState(groups = [group], df = df)
1602 mcastTraffic = McastTraffic([group], iface= tx_intf, cb = self.send_mcast_cb,
1603 arg = igmpState)
1604 mcastTraffic.start()
1605 time.sleep(1)
1606 join_state = IGMPProxyTestState(groups = [group])
1607 t = threading.Thread(target = self.verify_igmp_packets_on_proxy_interface)
1608 t.start()
1609 self.send_igmp_join(groups = [group], src_list = src,record_type = r_type,
1610 delay=1,iface = iface)
1611 t.join()
1612 assert_equal(self.status, True)
1613 if group is groups[0]:
1614 status = self.igmp_recv_task(iface, [group], join_state)
1615 else:
1616 status = self.igmp_not_recv_task(iface, [group], join_state)
1617 log_test.info('verified status for igmp recv task %s'%status)
1618 assert status == 1 , 'EXPECTED RESULT'
1619 except:
1620 log_test.info('Got some unexpected error %s'%error)
1621 raise
1622 mcastTraffic.stop()
1623 df.callback(0)
1624 reactor.callLater(0, igmp_proxy_test, df)
Chetan Gaonker26ae67e2017-07-18 19:58:30 +00001625 return df