1import logging, os, re 2from autotest_lib.client.common_lib import error 3from autotest_lib.client.bin import utils 4from autotest_lib.client.virt import virt_test_utils, aexpect 5 6 7def run_multicast(test, params, env): 8 """ 9 Test multicast function of nic (rtl8139/e1000/virtio) 10 11 1) Create a VM. 12 2) Join guest into multicast groups. 13 3) Ping multicast addresses on host. 14 4) Flood ping test with different size of packets. 15 5) Final ping test and check if lose packet. 16 17 @param test: KVM test object. 18 @param params: Dictionary with the test parameters. 19 @param env: Dictionary with test environment. 20 """ 21 vm = env.get_vm(params["main_vm"]) 22 vm.verify_alive() 23 session = vm.wait_for_login(timeout=int(params.get("login_timeout", 360))) 24 25 def run_guest(cmd): 26 try: 27 session.cmd(cmd) 28 except aexpect.ShellError, e: 29 logging.warning(e) 30 31 def run_host_guest(cmd): 32 run_guest(cmd) 33 utils.system(cmd, ignore_status=True) 34 35 # flush the firewall rules 36 cmd_flush = "iptables -F" 37 cmd_selinux = ("if [ -e /selinux/enforce ]; then setenforce 0; " 38 "else echo 'no /selinux/enforce file present'; fi") 39 run_host_guest(cmd_flush) 40 run_host_guest(cmd_selinux) 41 # make sure guest replies to broadcasts 42 cmd_broadcast = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts" 43 cmd_broadcast_2 = "echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all" 44 run_guest(cmd_broadcast) 45 run_guest(cmd_broadcast_2) 46 47 # base multicast address 48 mcast = params.get("mcast", "225.0.0.1") 49 # count of multicast addresses, less than 20 50 mgroup_count = int(params.get("mgroup_count", 5)) 51 flood_minutes = float(params.get("flood_minutes", 10)) 52 ifname = vm.get_ifname() 53 prefix = re.findall("\d+.\d+.\d+", mcast)[0] 54 suffix = int(re.findall("\d+", mcast)[-1]) 55 # copy python script to guest for joining guest to multicast groups 56 mcast_path = os.path.join(test.bindir, "scripts/multicast_guest.py") 57 vm.copy_files_to(mcast_path, "/tmp") 58 output = session.cmd_output("python /tmp/multicast_guest.py %d %s %d" % 59 (mgroup_count, prefix, suffix)) 60 61 # if success to join multicast, the process will be paused, and return PID. 62 try: 63 pid = re.findall("join_mcast_pid:(\d+)", output)[0] 64 except IndexError: 65 raise error.TestFail("Can't join multicast groups,output:%s" % output) 66 67 try: 68 for i in range(mgroup_count): 69 new_suffix = suffix + i 70 mcast = "%s.%d" % (prefix, new_suffix) 71 72 logging.info("Initial ping test, mcast: %s", mcast) 73 s, o = virt_test_utils.ping(mcast, 10, interface=ifname, timeout=20) 74 if s != 0: 75 raise error.TestFail(" Ping return non-zero value %s" % o) 76 77 logging.info("Flood ping test, mcast: %s", mcast) 78 virt_test_utils.ping(mcast, None, interface=ifname, flood=True, 79 output_func=None, timeout=flood_minutes*60) 80 81 logging.info("Final ping test, mcast: %s", mcast) 82 s, o = virt_test_utils.ping(mcast, 10, interface=ifname, timeout=20) 83 if s != 0: 84 raise error.TestFail("Ping failed, status: %s, output: %s" % 85 (s, o)) 86 87 finally: 88 logging.debug(session.cmd_output("ipmaddr show")) 89 session.cmd_output("kill -s SIGCONT %s" % pid) 90 session.close() 91