blob: 56d43a674086e0cde9cb1e23b284d5ca4962bd9b [file] [log] [blame]
alshabibd6be76e2016-03-01 22:21:00 -08001import oftest.base_tests as base_tests
alshabibcde318b2016-03-01 22:49:13 -08002from oftest import config
alshabibd6be76e2016-03-01 22:21:00 -08003import ofp
alshabibcde318b2016-03-01 22:49:13 -08004from oltconstants import *
Zsolt Haraszti5360d032016-03-02 23:02:09 -08005from oftest.testutils import *
alshabibcde318b2016-03-01 22:49:13 -08006import copy
Admin44f754e2016-03-01 23:00:46 -08007import logging
Zsolt Harasztid0571402016-03-02 18:40:50 -08008from IGMP import IGMPv3, IGMPv3gr, IGMP_TYPE_MEMBERSHIP_QUERY, \
9 IGMP_TYPE_V3_MEMBERSHIP_REPORT, IGMP_V3_GR_TYPE_EXCLUDE, \
10 IGMP_V3_GR_TYPE_INCLUDE
alshabibd6be76e2016-03-01 22:21:00 -080011
alshabibcde318b2016-03-01 22:49:13 -080012
alshabibd6be76e2016-03-01 22:21:00 -080013class OltBaseTest(base_tests.SimpleDataPlane):
14
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -080015 next_cookie_block = 40
16
17 def getCookieBlock(self):
18 """Returns the starting value of the next 100 cookies"""
19 c = self.next_cookie_block
20 OltBaseTest.next_cookie_block += 100
21 return c
22
23 def resetOlt(self):
24 """Reset the OLT into a clean healthy state"""
25 delete_all_flows(self.controller)
Zsolt Harasztid0571402016-03-02 18:40:50 -080026 delete_all_groups(self.controller)
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -080027 do_barrier(self.controller)
28 verify_no_errors(self.controller)
29
alshabibcde318b2016-03-01 22:49:13 -080030 def testPacketIn(self, match, parsed_pkt):
31 delete_all_flows(self.controller)
32
33 pkt = str(parsed_pkt)
34
35 for of_port in config["port_map"]:
36 m = copy.deepcopy(match)
37 m.oxm_list.append(ofp.oxm.in_port(of_port))
38 request = ofp.message.flow_add(
39 table_id=test_param_get("table", 0),
40 cookie=42,
41 match=m,
42 instructions=[
43 ofp.instruction.apply_actions(
44 actions=[
45 ofp.action.output(
46 port=ofp.OFPP_CONTROLLER,
47 max_len=ofp.OFPCML_NO_BUFFER)])],
48 buffer_id=ofp.OFP_NO_BUFFER,
49 priority=1000)
50 logging.info("Inserting flow sending matching packets to controller")
51 self.controller.message_send(request)
52 do_barrier(self.controller)
53
alshabib5339b7d2016-03-01 23:14:57 -080054 for of_port in config["port_map"]:
55 logging.info("PacketInExact test, port %d", of_port)
56 self.dataplane.send(of_port, pkt)
57 verify_packet_in(self, pkt, of_port, ofp.OFPR_ACTION)
58 verify_packets(self, pkt, [])
alshabibcde318b2016-03-01 22:49:13 -080059
Zsolt Haraszti5b8b39c2016-03-02 22:25:51 -080060 def installEapolRule(self, in_port=None, install=True):
61 in_port = onu_port if in_port is None else in_port
alshabibcde318b2016-03-01 22:49:13 -080062 match = ofp.match()
63 match.oxm_list.append(ofp.oxm.eth_type(0x888e))
64 match.oxm_list.append(ofp.oxm.in_port(in_port))
65 if install:
66 request = ofp.message.flow_add(
67 table_id=test_param_get("table", 0),
68 cookie=42,
69 match=match,
70 instructions=[
71 ofp.instruction.apply_actions(
72 actions=[
73 ofp.action.output(
74 port=ofp.OFPP_CONTROLLER,
75 max_len=ofp.OFPCML_NO_BUFFER)])],
76 buffer_id=ofp.OFP_NO_BUFFER,
77 priority=1000)
78 else:
Zsolt Haraszti5360d032016-03-02 23:02:09 -080079 request = ofp.message.flow_delete_strict(
alshabibcde318b2016-03-01 22:49:13 -080080 table_id=test_param_get("table", 0),
81 cookie=42,
82 match=match,
83 instructions=[
84 ofp.instruction.apply_actions(
85 actions=[
86 ofp.action.output(
87 port=ofp.OFPP_CONTROLLER,
88 max_len=ofp.OFPCML_NO_BUFFER)])],
89 buffer_id=ofp.OFP_NO_BUFFER,
90 priority=1000)
91 logging.info("%s flow sending matching packets to controller" % "Install" if install else "Remove")
92 self.controller.message_send(request)
93 do_barrier(self.controller)
94
Zsolt Haraszti5b8b39c2016-03-02 22:25:51 -080095 def sendEapolIn(self, in_port=None):
96 """Send in an EAPOL frame and verify that the controller receives it"""
97
98 in_port = onu_port if in_port is None else in_port
99 pkt = str(simple_eth_packet(eth_dst='01:00:5e:7f:ff:ff', eth_type=0x888e, pktlen=60))
100 self.dataplane.send(in_port, pkt)
101 verify_packet_in(self, pkt, in_port, ofp.OFPR_ACTION)
102 verify_packets(self, pkt, [])
103
Zsolt Haraszti5360d032016-03-02 23:02:09 -0800104 def sendEapolOut(self, out_port=None):
105 """Send out an EAPOL frame and verify that it is sent out at the given ONU port"""
106 out_port = onu_port if out_port is None else out_port
107 pkt = simple_eth_packet(eth_dst='01:02:03:04:05:06', eth_src='01:02:03:de:ad:be',
108 eth_type=0x888e, pktlen=300)
109
110 msg = ofp.message.packet_out(
111 in_port=ofp.OFPP_CONTROLLER,
112 actions=[ofp.action.output(port=out_port)],
113 buffer_id=ofp.OFP_NO_BUFFER,
114 data=str(pkt))
115
116 rv = self.controller.message_send(msg)
117 self.assertTrue(rv == 0, "Error sending output message")
118 verify_no_errors(self.controller)
119
120 verify_packet(self, pkt, out_port)
121
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -0800122 def testPacketFlow(self,
123 s_vlan_id,
124 c_vlan_id,
125 onu=None,
126 verify_blocked_flows=True,
127 pktlen=96):
alshabibcde318b2016-03-01 22:49:13 -0800128
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -0800129 incorrectTagPkt = simple_udp_packet(
130 pktlen=pktlen+4, dl_vlan_enable=True, vlan_vid=s_vlan_id, vlan_pcp=1)
131 zeroTaggedPkt = simple_udp_packet(
132 pktlen=pktlen+4, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
133 untaggedPkt = simple_udp_packet(pktlen=pktlen)
134 upstreamDoubleTaggedPkt = double_vlan_udp_packet(
135 pktlen=pktlen+8, dl_vlan_enable=True, c_vlan_vid=c_vlan_id, s_vlan_vid=s_vlan_id,
136 c_vlan_pcp=0, s_vlan_pcp=0)
alshabibcde318b2016-03-01 22:49:13 -0800137
alshabib5339b7d2016-03-01 23:14:57 -0800138 inport = onu_port if onu is None else onu
139
alshabibcde318b2016-03-01 22:49:13 -0800140 logging.info("Testing s-tag %d, c-tag %d" % (s_vlan_id, c_vlan_id))
141
142 # test upstream untagged packet got double tag at OLT
alshabib5339b7d2016-03-01 23:14:57 -0800143 self.dataplane.send(inport, str(zeroTaggedPkt))
Admin44f754e2016-03-01 23:00:46 -0800144 verify_packet(self, upstreamDoubleTaggedPkt, olt_port)
alshabibcde318b2016-03-01 22:49:13 -0800145
146 # test downstream doubletagged packet got untagged at ONU
147 self.dataplane.send(olt_port, str(upstreamDoubleTaggedPkt))
148 if device_type == "pmc":
alshabib5339b7d2016-03-01 23:14:57 -0800149 verify_packet(self, zeroTaggedPkt, inport)
alshabibcde318b2016-03-01 22:49:13 -0800150 else:
alshabib5339b7d2016-03-01 23:14:57 -0800151 verify_packet(self, untaggedPkt, inport)
alshabibcde318b2016-03-01 22:49:13 -0800152
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -0800153 if verify_blocked_flows:
154 # test upstream doubletagged packet got dropped
155 self.dataplane.send(inport, str(upstreamDoubleTaggedPkt))
156 verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
alshabibcde318b2016-03-01 22:49:13 -0800157
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -0800158 # test downstream untagged packet got dropped at ONU
159 self.dataplane.send(olt_port, str(untaggedPkt))
160 verify_no_packet(self, untaggedPkt, inport)
alshabibcde318b2016-03-01 22:49:13 -0800161
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -0800162 # test upstream icorrectly tagged packet; should get dropped
163 self.dataplane.send(inport, str(incorrectTagPkt))
164 verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
165
166 def testSustainedPacketFlow(self, s_vlan_id, c_vlan_id, number_of_roundtrips=10, onu=None):
167 for i in xrange(number_of_roundtrips):
Zsolt Harasztid0571402016-03-02 18:40:50 -0800168 print "pkt # %d" % (i+1,)
Zsolt Harasztif5c6aba2016-03-02 11:41:22 -0800169 self.testPacketFlow(s_vlan_id, c_vlan_id, onu=onu, verify_blocked_flows=False)
alshabibcde318b2016-03-01 22:49:13 -0800170
Zsolt Haraszti5360d032016-03-02 23:02:09 -0800171 def installDoubleTaggingRules(self, s_vlan_id, c_vlan_id, cookie=42, onu=None):
alshabib5339b7d2016-03-01 23:14:57 -0800172
173 inport = onu_port if onu is None else onu
alshabibd6be76e2016-03-01 22:21:00 -0800174
175 # upstream flow rule
176 match = ofp.match()
alshabib5339b7d2016-03-01 23:14:57 -0800177 match.oxm_list.append(ofp.oxm.in_port(inport))
alshabibd6be76e2016-03-01 22:21:00 -0800178 if device_type == "cpqd":
179 match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_NONE))
180 actions = [
181 ofp.action.push_vlan(ethertype=0x8100),
182 ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id)),
183 ofp.action.set_field(ofp.oxm.vlan_pcp(0))
184 ]
185 else: # "pmc", "normal"
186 match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_PRESENT))
187 match.oxm_list.append(ofp.oxm.vlan_pcp(value=0))
188 actions = [
189 ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
190 ]
191 cookie += 1
192
193 # push inner vlan (c-vlan) for upstream
194 request = ofp.message.flow_add(
195 table_id=test_param_get("table", 0),
196 cookie=cookie,
197 match=match,
198 instructions=[
199 ofp.instruction.apply_actions(actions=actions),
200 ofp.instruction.goto_table(1)],
201 buffer_id=ofp.OFP_NO_BUFFER,
202 priority=1000)
203
204 self.controller.message_send(request)
205 do_barrier(self.controller)
206 verify_no_errors(self.controller)
207
208 # push outer vlan (s-vlan) for upstream
209 match = ofp.match()
alshabib5339b7d2016-03-01 23:14:57 -0800210 match.oxm_list.append(ofp.oxm.in_port(inport))
alshabibd6be76e2016-03-01 22:21:00 -0800211 match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
212 match.oxm_list.append(ofp.oxm.vlan_pcp(0))
213 cookie += 1
214
215 request = ofp.message.flow_add(
216 table_id=test_param_get("table", 1),
217 cookie=cookie,
218 match=match,
219 instructions=[
220 ofp.instruction.apply_actions(
221 actions=[
222 ofp.action.push_vlan(ethertype=0x8100),
223 ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id)),
224 ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
225 ofp.action.output(port=olt_port)]),
226 ],
227 buffer_id=ofp.OFP_NO_BUFFER,
228 priority=1000)
229
230 self.controller.message_send(request)
231 do_barrier(self.controller)
232 verify_no_errors(self.controller)
233 cookie += 1
234
235 # strip outer vlan (s-vlan) for downstream
236 match = ofp.match()
237 match.oxm_list.append(ofp.oxm.in_port(olt_port))
238 match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | s_vlan_id))
239 match.oxm_list.append(ofp.oxm.vlan_pcp(0))
240 request = ofp.message.flow_add(
241 table_id=test_param_get("table", 0),
242 cookie=cookie,
243 match=match,
244 instructions=[
245 ofp.instruction.apply_actions(
246 actions=[ofp.action.pop_vlan()]),
247 ofp.instruction.goto_table(1)],
248 buffer_id=ofp.OFP_NO_BUFFER,
249 priority=1000)
250
251 self.controller.message_send(request)
252 do_barrier(self.controller)
253 verify_no_errors(self.controller)
254
255 # rewrite inner vlan (c-vlan) to default (0) for downstream
256 match = ofp.match()
257 match.oxm_list.append(ofp.oxm.in_port(olt_port))
258 match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | c_vlan_id))
259 match.oxm_list.append(ofp.oxm.vlan_pcp(0))
260 cookie += 1
261
262 request = ofp.message.flow_add(
263 table_id=test_param_get("table", 1),
264 cookie=cookie,
265 match=match,
266 instructions=[
267 ofp.instruction.apply_actions(
268 actions=[
269 ofp.action.pop_vlan(),
alshabib5339b7d2016-03-01 23:14:57 -0800270 ofp.action.output(port=inport)])
alshabibd6be76e2016-03-01 22:21:00 -0800271 ],
272 buffer_id=ofp.OFP_NO_BUFFER,
273 priority=1000)
274
275 self.controller.message_send(request)
276 do_barrier(self.controller)
277 verify_no_errors(self.controller)
Zsolt Harasztid0571402016-03-02 18:40:50 -0800278
Zsolt Haraszti5b8b39c2016-03-02 22:25:51 -0800279 def installIgmpRule(self, cookie):
Zsolt Harasztid0571402016-03-02 18:40:50 -0800280 """Etsablish flow rules that will forward any incoming
281 IGMP packets to controller (from any port, OLT and ONUs)
282 """
283 match = ofp.match()
284 match.oxm_list.append(ofp.oxm.eth_type(0x800))
285 match.oxm_list.append(ofp.oxm.ip_proto(2))
286 request = ofp.message.flow_add(
287 table_id=test_param_get("table", 0),
288 cookie=42,
289 match=match,
290 instructions=[
291 ofp.instruction.apply_actions(
292 actions=[
293 ofp.action.output(
294 port=ofp.OFPP_CONTROLLER,
295 max_len=ofp.OFPCML_NO_BUFFER)])],
296 buffer_id=ofp.OFP_NO_BUFFER,
297 priority=2000)
298 logging.info("Inserting flow sending matching packets to controller")
299 self.controller.message_send(request)
300 do_barrier(self.controller)
301
302 def testIgmpQueryOut(self, onu=None):
303 """Send an IGMP Query out to given onu and verify that it arrives"""
304
305 outport = onu_port if onu is None else onu
306
307 igmp = IGMPv3() # by default this is a query
308 pkt = self.buildIgmp(igmp)
309
310 msg = ofp.message.packet_out(
311 in_port=ofp.OFPP_CONTROLLER,
312 actions=[ofp.action.output(port=outport)],
313 buffer_id=ofp.OFP_NO_BUFFER,
314 data=str(pkt))
315
316 self.controller.message_send(msg)
317
318 rv = self.controller.message_send(msg)
319 self.assertTrue(rv == 0, "Error sending output message")
320 verify_no_errors(self.controller)
321
322 verify_packet(self, pkt, outport)
323
324 def sendIgmpReport(self, join=[], leave=[], onu=None, srcmac=None,
325 ip_src='1.2.3.4', ip_dst='2440.0.0.22', pad_to=None):
326 """Send an IGMP Join request from given onu to given mcast group"""
327
328 # construct packet
329 in_port = onu_port if onu is None else onu
330 src_mac = '00:00:00:00:be:ef' if srcmac is None else srcmac
331 pkt = str(self.buildIgmpReport(ip_src, ip_dst, src_mac, join, leave, pad_to=pad_to))
332
333 # send packet via in_port
334 self.dataplane.send(in_port, pkt)
335
336 # verify it is received by controller and not by some other port
337 verify_packet_in(self, pkt, in_port, ofp.OFPR_ACTION)
338 verify_packets(self, pkt, [])
339
340 def buildIgmpReport(self, ip_src, ip_dst, srcmac, join=[], leave=[], sources={}, pad_to=None):
341 """ Return an IGMPv4 Membership Report as a scapy Ethernet frame
342 join: a list of multicast addresses that shall be joined
343 leave: a list of multicast addresses that shall be left
344 sources: a dict of source lists keyed by the mcast address that needs to be joined
345 or left.
346 """
347
348 assert join or leave, "Either join or leave must be a non-empty list"
349
350 igmp = IGMPv3(type=IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30, gaddr="224.0.0.1")
351
352 for mcast_group in join:
353 srcs = sources.get(mcast_group, [])
354 if len(srcs):
355 gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_INCLUDE, mcaddr=mcast_group)
356 gr.sources = srcs
357 else:
358 gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_EXCLUDE, mcaddr=mcast_group)
359 igmp.grps.append(gr)
360
361 for mcast_group in leave:
362 gr = IGMPv3gr(rtype=IGMP_V3_GR_TYPE_INCLUDE, mcaddr=mcast_group)
363 igmp.grps.append(gr)
364
365 pkt = IGMPv3.fixup( scapy.Ether(src=srcmac) / scapy.IP() / igmp )
366 pkt = self.padPktTo(pkt, pad_to)
367 return pkt
368
369 def buildIgmp(self, payload, pad_to=None):
370 pkt = IGMPv3.fixup(scapy.Ether() / scapy.IP() / payload)
371 return self.padPktTo(pkt, pad_to)
372
373 def padPktTo(self, pkt, pad_to=None):
374 """If pad_to is provided, it shall be an integer. If pkt is smaller than that number,
375 it will be properly padded (ethernet padding) and returned. Otherwise the original
376 pkt is returned.
377 """
378 if pad_to is None:
379 return pkt
380
381 pad_len = pad_to - len(pkt)
382 if pad_len > 0:
383 pad = scapy.scapy.layers.l2.Padding()
384 pad.load = '\x00' * pad_len
385 pkt = pkt / pad
386 return pkt
387
388 def setupMcastChannel(self, mcast_addr, mcast_vlan_id, port_list, group_id=1, cookie=100):
389 """Setup multicast forwarding for the mcast address using mcast vlan id
390 and given port list.
391 """
392
393 # setup group first with given port list
394
395 buckets = [
396 ofp.common.bucket(
397 watch_port=ofp.OFPP_ANY,
398 watch_group=ofp.OFPG_ANY,
399 actions=[
400 ofp.action.pop_vlan(),
401 ofp.action.output(port=port)
402 ])
403 for port in port_list
404 ]
405
406 msg = ofp.message.group_add(
407 group_type=ofp.OFPGT_ALL,
408 group_id=group_id,
409 buckets=buckets
410 )
411
412 self.controller.message_send(msg)
413 do_barrier(self.controller)
414 verify_no_errors(self.controller)
415
416 # Then setup flow rule pointing to group
417
418 match = ofp.match()
419 match.oxm_list.append(ofp.oxm.in_port(olt_port))
420 match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | mcast_vlan_id))
421 match.oxm_list.append(ofp.oxm.eth_type(0x800))
422 match.oxm_list.append(ofp.oxm.ipv4_dst(self.ip2int(mcast_addr)))
423 request = ofp.message.flow_add(
424 table_id=test_param_get("table", 0),
425 cookie=cookie,
426 match=match,
427 instructions=[
428 ofp.instruction.apply_actions(
429 actions=[ofp.action.group(group_id=group_id)]),
430 ],
431 buffer_id=ofp.OFP_NO_BUFFER, priority=1000)
432 self.controller.message_send(request)
433 do_barrier(self.controller)
434 verify_no_errors(self.controller)
435
436 def removeMcastChannel(self, mcast_addr, mcast_vlan_id, port_list, group_id, cookie):
437 """Remove mumticast forwarding for given mcast address"""
438
439 # Remove flow first
440 match = ofp.match()
441 match.oxm_list.append(ofp.oxm.in_port(olt_port))
442 match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | mcast_vlan_id))
443 match.oxm_list.append(ofp.oxm.eth_type(0x800))
444 match.oxm_list.append(ofp.oxm.ipv4_dst(self.ip2int(mcast_addr)))
445 request = ofp.message.flow_delete(
446 table_id=test_param_get("table", 0),
447 cookie=cookie,
448 match=match,
449 instructions=[
450 ofp.instruction.apply_actions(
451 actions=[ofp.action.group(group_id=group_id)]),
452 ],
453 buffer_id=ofp.OFP_NO_BUFFER, priority=1000)
454 self.controller.message_send(request)
455 do_barrier(self.controller)
456 verify_no_errors(self.controller)
457
458 # Then remove the group
459 group_delete = ofp.message.group_delete(group_id=group_id)
460 self.controller.message_send(group_delete)
461 do_barrier(self.controller)
462 verify_no_errors(self.controller)
463
Zsolt Haraszti5360d032016-03-02 23:02:09 -0800464 def updateMcastChannel(self, group_id, port_list):
465 """Modify the group port list by adding/removing ports"""
466
467 buckets = [
468 ofp.common.bucket(
469 watch_port=ofp.OFPP_ANY,
470 watch_group=ofp.OFPG_ANY,
471 actions=[
472 ofp.action.pop_vlan(),
473 ofp.action.output(port=port)
474 ])
475 for port in port_list
476 ]
477
478 msg = ofp.message.group_mod(
479 command=ofp.OFPGC_MODIFY,
480 group_type=ofp.OFPGT_ALL,
481 group_id=group_id,
482 buckets=buckets)
483
484 self.controller.message_send(msg)
485 do_barrier(self.controller)
486 verify_no_errors(self.controller)
487
Zsolt Harasztid0571402016-03-02 18:40:50 -0800488 def ip2int(self, ip):
489 """Convert a dot-notated string IP address"""
490 digits = [int(d) for d in ip.split('.')]
491 assert len(digits) == 4
492 val = (
493 (digits[0] & 0xff) << 24 |
494 (digits[1] & 0xff) << 16 |
495 (digits[2] & 0xff) << 8 |
496 (digits[3] & 0xff))
497 return val
498
499 def mcastIp2McastMac(self, ip):
500 """ Convert a dot-notated IPv4 multicast address string into an multicast MAC address"""
501 digits = [int(d) for d in ip.split('.')]
502 return '01:00:5e:%02x:%02x:%02x' % (digits[1] & 0x7f, digits[2] & 0xff, digits[3] & 0xff)
503
504 def testMcastFlow(self, mcast_addr, mcast_vlan_id, ports=None, numpkt=1, ip_src="66.77.88.99",
505 expect_to_be_blocked=False):
506 """ Send given number of mcast packets using mcast address and vlan_id
507 and check they arrive to given port(s).
508 """
509
510 # construct mcast packet
511 pktlen = 250
512 pktToSend = simple_udp_packet(
513 eth_dst=self.mcastIp2McastMac(mcast_addr),
514 ip_src=ip_src,
515 ip_dst=mcast_addr,
516 pktlen=pktlen+4,
517 dl_vlan_enable=True,
518 vlan_vid=mcast_vlan_id,
519 vlan_pcp=0)
520
521 if device_type == "pmc":
522 pktToReceive = simple_udp_packet(
523 eth_dst=self.mcastIp2McastMac(mcast_addr),
524 ip_src=ip_src,
525 ip_dst=mcast_addr,
526 pktlen=pktlen+4,
527 dl_vlan_enable=True,
528 vlan_vid=0,
529 vlan_pcp=0)
530 else:
531 pktToReceive = simple_udp_packet(
532 eth_dst=self.mcastIp2McastMac(mcast_addr),
533 ip_src=ip_src,
534 ip_dst=mcast_addr,
535 pktlen=pktlen)
536
537 # send mcast packet to olt
538 self.dataplane.send(olt_port, str(pktToSend))
539
540 # test that packet is received on each designated port
541 ports = [onu_port] if ports is None else ports
542 for port in ports:
543 if expect_to_be_blocked:
544 verify_no_packet(self, pktToReceive, port)
545 else:
546 verify_packet(self, pktToReceive, port)