From ee880bfa987d6ec743c8bec89ad481e5a93c5c16 Mon Sep 17 00:00:00 2001 From: "Houqi (Nick) Zuo" Date: Tue, 14 May 2024 14:27:21 +0800 Subject: [PATCH] net/macvtap.py: refactor module Refactor the utils_net.py: 1. Split net_driver/macvtap module from utils_net module. Signed-off-by: Houqi (Nick) Zuo --- virttest/vt_utils/net_driver/macvtap.py | 126 ++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 virttest/vt_utils/net_driver/macvtap.py diff --git a/virttest/vt_utils/net_driver/macvtap.py b/virttest/vt_utils/net_driver/macvtap.py new file mode 100644 index 0000000000..e1a2e7b16d --- /dev/null +++ b/virttest/vt_utils/net_driver/macvtap.py @@ -0,0 +1,126 @@ +# Library for the macvtap address related functions. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; specifically version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# See LICENSE for more details. +# +# Copyright: Red Hat (c) 2024 and Avocado contributors +# Author: Houqi Zuo +import os + +from avocado.utils import process + +from virttest import arch, utils_misc +from virttest.vt_utils.net import interface as iface + + +def create_macvtap(iface=None, tapname=None, mode="vepa", mac_addr=None): + """ + Create a Macvtap device. + + :param iface: The physical interface. + :type iface: String. + :param tapname: The macvtap name. + :type tapname: String. + :param mode: The macvtap type mode (vepa, bridge, private) + :type mode: String. + :param mac_addr: The macvtap mac address. + :type mac_addr: String. + + :raise: A RuntimeError may be raised if running command fails. + """ + if not iface: + iface = get_macvtap_base_iface(iface) + if not tapname: + tapname = "macvtap" + utils_misc.generate_random_id() + cmd = "ip link add link %s name %s type %s" % (iface, tapname, mode) + process.run(cmd, shell=True) + if mac_addr: + cmd = "ip link set %s address %s up" % (tapname, mac_addr) + process.run(cmd, shell=True) + + +def show_macvtap(tapname): + """ + Show the macvtap details. + + :param tapname: The macvtap name. + :type tapname: String. + + :return: The macvtap details. + :rtype: String. + """ + cmd = "ip link show %s" % tapname + cmd_obj = process.run(cmd, shell=True) + return cmd_obj.stdout_text.strip() + + +def delete_macvtap(tapname): + """ + Delete the macvtap. + + :param tapname: The macvtap name. + :type tapname: String. + """ + cmd = "ip link delete %s" % tapname + process.run(cmd, shell=True) + + +def get_macvtap_base_iface(base_interface=None): + """ + Get physical interface to create macvtap, if you assigned base interface + is valid(not belong to any bridge and is up), will use it; else use the + first physical interface, which is not a brport and up. + """ + tap_base_device = None + + (dev_int, _) = iface.get_sorted_net_if() + + if base_interface and base_interface in dev_int: + if (not iface.net_if_is_brport(base_interface)) and ( + iface.is_iface_flag_same(base_interface, arch.IFF_UP) + ): + tap_base_device = base_interface + + if not tap_base_device: + for interface in dev_int: + if iface.net_if_is_brport(interface): + continue + if iface.is_iface_flag_same(interface, arch.IFF_UP): + tap_base_device = interface + break + + return tap_base_device + + +def open_macvtap(macvtap, queues=1): + """ + Open a macvtap device and returns its file descriptors which are used by + fds= parameter of qemu. + + For single queue, only returns one file descriptor, it's used by + fd= legacy parameter of qemu. + + If you not have a switch support vepa in you env, run this type case you + need at least two nic on you host [just workaround]. + + :param macvtap: The macvtap name. + :type macvtap: String. + :param queues: Queue number. + :type queues: Integer. + + :return: The file descriptors which are used + by fds= parameter of qemu. + :rtype: String. + """ + tapfds = [] + macvtap = "/dev/%s" % macvtap + for queue in range(int(queues)): + tapfds.append(str(os.open(macvtap, os.O_RDWR))) + return ":".join(tapfds)