1import logging, time, re 2from autotest_lib.client.common_lib import error 3from autotest_lib.client.virt import virt_utils, virt_test_utils, aexpect 4 5 6def run_vlan(test, params, env): 7 """ 8 Test 802.1Q vlan of NIC, config it by vconfig command. 9 10 1) Create two VMs. 11 2) Setup guests in 10 different vlans by vconfig and using hard-coded 12 ip address. 13 3) Test by ping between same and different vlans of two VMs. 14 4) Test by TCP data transfer, floop ping between same vlan of two VMs. 15 5) Test maximal plumb/unplumb vlans. 16 6) Recover the vlan config. 17 18 @param test: KVM test object. 19 @param params: Dictionary with the test parameters. 20 @param env: Dictionary with test environment. 21 """ 22 vm = [] 23 session = [] 24 ifname = [] 25 vm_ip = [] 26 digest_origin = [] 27 vlan_ip = ['', ''] 28 ip_unit = ['1', '2'] 29 subnet = params.get("subnet") 30 vlan_num = int(params.get("vlan_num")) 31 maximal = int(params.get("maximal")) 32 file_size = params.get("file_size") 33 34 vm.append(env.get_vm(params["main_vm"])) 35 vm.append(env.get_vm("vm2")) 36 for vm_ in vm: 37 vm_.verify_alive() 38 39 def add_vlan(session, v_id, iface="eth0"): 40 session.cmd("vconfig add %s %s" % (iface, v_id)) 41 42 def set_ip_vlan(session, v_id, ip, iface="eth0"): 43 iface = "%s.%s" % (iface, v_id) 44 session.cmd("ifconfig %s %s" % (iface, ip)) 45 46 def set_arp_ignore(session, iface="eth0"): 47 ignore_cmd = "echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore" 48 session.cmd(ignore_cmd) 49 50 def rem_vlan(session, v_id, iface="eth0"): 51 rem_vlan_cmd = "if [[ -e /proc/net/vlan/%s ]];then vconfig rem %s;fi" 52 iface = "%s.%s" % (iface, v_id) 53 return session.cmd_status(rem_vlan_cmd % (iface, iface)) 54 55 def nc_transfer(src, dst): 56 nc_port = virt_utils.find_free_port(1025, 5334, vm_ip[dst]) 57 listen_cmd = params.get("listen_cmd") 58 send_cmd = params.get("send_cmd") 59 60 #listen in dst 61 listen_cmd = listen_cmd % (nc_port, "receive") 62 session[dst].sendline(listen_cmd) 63 time.sleep(2) 64 #send file from src to dst 65 send_cmd = send_cmd % (vlan_ip[dst], str(nc_port), "file") 66 session[src].cmd(send_cmd, timeout=60) 67 try: 68 session[dst].read_up_to_prompt(timeout=60) 69 except aexpect.ExpectError: 70 raise error.TestFail ("Fail to receive file" 71 " from vm%s to vm%s" % (src+1, dst+1)) 72 #check MD5 message digest of receive file in dst 73 output = session[dst].cmd_output("md5sum receive").strip() 74 digest_receive = re.findall(r'(\w+)', output)[0] 75 if digest_receive == digest_origin[src]: 76 logging.info("file succeed received in vm %s", vlan_ip[dst]) 77 else: 78 logging.info("digest_origin is %s", digest_origin[src]) 79 logging.info("digest_receive is %s", digest_receive) 80 raise error.TestFail("File transfered differ from origin") 81 session[dst].cmd_output("rm -f receive") 82 83 for i in range(2): 84 session.append(vm[i].wait_for_login( 85 timeout=int(params.get("login_timeout", 360)))) 86 if not session[i] : 87 raise error.TestError("Could not log into guest(vm%d)" % i) 88 logging.info("Logged in") 89 90 ifname.append(virt_test_utils.get_linux_ifname(session[i], 91 vm[i].get_mac_address())) 92 #get guest ip 93 vm_ip.append(vm[i].get_address()) 94 95 #produce sized file in vm 96 dd_cmd = "dd if=/dev/urandom of=file bs=1024k count=%s" 97 session[i].cmd(dd_cmd % file_size) 98 #record MD5 message digest of file 99 output = session[i].cmd("md5sum file", timeout=60) 100 digest_origin.append(re.findall(r'(\w+)', output)[0]) 101 102 #stop firewall in vm 103 session[i].cmd_output("/etc/init.d/iptables stop") 104 105 #load 8021q module for vconfig 106 session[i].cmd("modprobe 8021q") 107 108 try: 109 for i in range(2): 110 for vlan_i in range(1, vlan_num+1): 111 add_vlan(session[i], vlan_i, ifname[i]) 112 set_ip_vlan(session[i], vlan_i, "%s.%s.%s" % 113 (subnet, vlan_i, ip_unit[i]), ifname[i]) 114 set_arp_ignore(session[i], ifname[i]) 115 116 for vlan in range(1, vlan_num+1): 117 logging.info("Test for vlan %s", vlan) 118 119 logging.info("Ping between vlans") 120 interface = ifname[0] + '.' + str(vlan) 121 for vlan2 in range(1, vlan_num+1): 122 for i in range(2): 123 interface = ifname[i] + '.' + str(vlan) 124 dest = subnet +'.'+ str(vlan2)+ '.' + ip_unit[(i+1)%2] 125 s, o = virt_test_utils.ping(dest, count=2, 126 interface=interface, 127 session=session[i], timeout=30) 128 if ((vlan == vlan2) ^ (s == 0)): 129 raise error.TestFail ("%s ping %s unexpected" % 130 (interface, dest)) 131 132 vlan_ip[0] = subnet + '.' + str(vlan) + '.' + ip_unit[0] 133 vlan_ip[1] = subnet + '.' + str(vlan) + '.' + ip_unit[1] 134 135 logging.info("Flood ping") 136 def flood_ping(src, dst): 137 # we must use a dedicated session becuase the aexpect 138 # does not have the other method to interrupt the process in 139 # the guest rather than close the session. 140 session_flood = vm[src].wait_for_login(timeout=60) 141 virt_test_utils.ping(vlan_ip[dst], flood=True, 142 interface=ifname[src], 143 session=session_flood, timeout=10) 144 session_flood.close() 145 146 flood_ping(0, 1) 147 flood_ping(1, 0) 148 149 logging.info("Transfering data through nc") 150 nc_transfer(0, 1) 151 nc_transfer(1, 0) 152 153 finally: 154 for vlan in range(1, vlan_num+1): 155 rem_vlan(session[0], vlan, ifname[0]) 156 rem_vlan(session[1], vlan, ifname[1]) 157 logging.info("rem vlan: %s", vlan) 158 159 # Plumb/unplumb maximal number of vlan interfaces 160 i = 1 161 s = 0 162 try: 163 logging.info("Testing the plumb of vlan interface") 164 for i in range (1, maximal+1): 165 add_vlan(session[0], i, ifname[0]) 166 finally: 167 for j in range (1, i+1): 168 s = s or rem_vlan(session[0], j, ifname[0]) 169 if s == 0: 170 logging.info("maximal interface plumb test done") 171 else: 172 logging.error("maximal interface plumb test failed") 173 174 session[0].close() 175 session[1].close() 176