diff --git a/test/case/ietf_interfaces/static_multicast_filters/Readme.adoc b/test/case/ietf_interfaces/static_multicast_filters/Readme.adoc index 33bcccf9..9fc1e6ad 100644 --- a/test/case/ietf_interfaces/static_multicast_filters/Readme.adoc +++ b/test/case/ietf_interfaces/static_multicast_filters/Readme.adoc @@ -35,9 +35,14 @@ endif::topdoc[] . Configure device without static filter . Start multicast sender on host:data1, group 224.1.1.1 . Verify that 224.1.1.1 is flooded to host:data2 and host:data3 -. Enable multicast filter on host:data2, group 224.1.1.1 +. Enable IPv4 multicast filter on host:data2, group 224.1.1.1 . Verify that the group is still forwarded to host:data2 . Verify that the group is no longer forwarded to host:data3 +. Start MAC multicast sender on host:data1, group 01:00:00:01:02:03 +. Verify MAC multicast 01:00:00:01:02:03 is flooded to host:data2 and host:data3 +. Enable MAC multicast filter on host:data2, group 01:00:00:01:02:03 +. Verify that the MAC group is still forwarded to host:data2 +. Verify that the MAC group is no longer forwarded to host:data3 <<< diff --git a/test/case/ietf_interfaces/static_multicast_filters/test.py b/test/case/ietf_interfaces/static_multicast_filters/test.py index 5a5d99da..afc79837 100755 --- a/test/case/ietf_interfaces/static_multicast_filters/test.py +++ b/test/case/ietf_interfaces/static_multicast_filters/test.py @@ -25,8 +25,8 @@ enabled when using static multicast filters) HOST .... """ + import infamy -import time import infamy.multicast as mcast import infamy.iface as iface from infamy.util import until @@ -64,6 +64,9 @@ with infamy.Test() as test: _, mreceive = env.ltop.xlate("target", "data2") _, nojoin = env.ltop.xlate("target", "data3") + ipv4_multicast_group = "224.1.1.1" + mac_multicast_group = "01:00:00:01:02:03" + with test.step("Configure device without static filter"): target.put_config_dict("ietf-interfaces", { @@ -128,20 +131,42 @@ with infamy.Test() as test: receive_ns.must_reach("10.0.0.1") nojoin_ns.must_reach("10.0.0.1") - print("Starting sender") - with mcast.MCastSender(send_ns, "224.1.1.1"): + print("Starting IPv4 multicast sender") + with mcast.MCastSender(send_ns, ipv4_multicast_group): + with test.step("Verify that 224.1.1.1 is flooded to host:data2 and host:data3"): - infamy.parallel(lambda: receive_ns.must_receive("ip dst 224.1.1.1"), - lambda: nojoin_ns.must_receive("ip dst 224.1.1.1")) + infamy.parallel( + lambda: receive_ns.must_receive(f"ip dst {ipv4_multicast_group}"), + lambda: nojoin_ns.must_receive(f"ip dst {ipv4_multicast_group}")) - with test.step("Enable multicast filter on host:data2, group 224.1.1.1"): - set_static_multicast_filter(target, "224.1.1.1", mreceive) - until(lambda: iface.exist_bridge_multicast_filter(target, "224.1.1.1", mreceive, "br0")) + with test.step("Enable IPv4 multicast filter on host:data2, group 224.1.1.1"): + set_static_multicast_filter(target, ipv4_multicast_group, mreceive) + until(lambda: iface.exist_bridge_multicast_filter(target, ipv4_multicast_group, mreceive, "br0")) with test.step("Verify that the group is still forwarded to host:data2"): - receive_ns.must_receive("ip dst 224.1.1.1") + receive_ns.must_receive(f"ip dst {ipv4_multicast_group}") with test.step("Verify that the group is no longer forwarded to host:data3"): - nojoin_ns.must_not_receive("ip dst 224.1.1.1") + nojoin_ns.must_not_receive(f"ip dst {ipv4_multicast_group}") - test.succeed() + with test.step("Start MAC multicast sender on host:data1, group 01:00:00:01:02:03"): + + print("Starting MAC multicast sender") + with mcast.MacMCastSender(send_ns, mac_multicast_group): + + with test.step("Verify MAC multicast 01:00:00:01:02:03 is flooded to host:data2 and host:data3"): + infamy.parallel( + lambda: receive_ns.must_receive(f"ether dst {mac_multicast_group}"), + lambda: nojoin_ns.must_receive(f"ether dst {mac_multicast_group}")) + + with test.step("Enable MAC multicast filter on host:data2, group 01:00:00:01:02:03"): + set_static_multicast_filter(target, mac_multicast_group, mreceive) + until(lambda: iface.exist_bridge_multicast_filter(target, mac_multicast_group, mreceive, "br0")) + + with test.step("Verify that the MAC group is still forwarded to host:data2"): + receive_ns.must_receive(f"ether dst {mac_multicast_group}"), + + with test.step("Verify that the MAC group is no longer forwarded to host:data3"): + nojoin_ns.must_not_receive(f"ether dst {mac_multicast_group}") + + test.succeed() diff --git a/test/infamy/multicast.py b/test/infamy/multicast.py index f7226e43..735838e6 100644 --- a/test/infamy/multicast.py +++ b/test/infamy/multicast.py @@ -2,6 +2,7 @@ import time import subprocess import signal import sys +from scapy.all import Ether, sendp class MCastSender: def __init__(self, netns,group): @@ -54,3 +55,29 @@ class MCastReceiver: print("ERR") pass self.proc.wait() + +class MacMCastSender: + def __init__(self, netns, group): + self.group = group + self.netns = netns + + def __enter__(self): + send_cmd = ( + "from scapy.all import sendp, Ether; " + f"pkt=Ether(src='aa:bb:cc:dd:ee:ff', dst='{self.group}', type=0xdead); " + "sendp(pkt, iface='iface', count=50, inter=1./10)" + ) + self.proc = self.netns.popen(["python3", "-c", send_cmd], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return self + + def __exit__(self, _, __, ___): + if self.proc: + sys.stdout.flush() + self.proc.send_signal(signal.SIGINT) + time.sleep(1) + if not self.proc.poll(): + try: + self.proc.kill() + except OSError: + pass + self.proc.wait()