From de938b92c9d3a47647164aa643c20d2fc96cd2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Fri, 1 Feb 2019 12:39:25 +0000 Subject: [PATCH] util: add helper method for re-attaching a tap device to a bridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Cole Robinson Signed-off-by: Daniel P. Berrangé --- src/libvirt_private.syms | 1 + src/util/virnetdevtap.c | 67 ++++++++++++++++++++++++++++++++++++++++ src/util/virnetdevtap.h | 12 +++++++ 3 files changed, 80 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b2be2d0fb9..a7817e8b35 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2486,6 +2486,7 @@ virNetDevTapDelete; virNetDevTapGetName; virNetDevTapGetRealDeviceName; virNetDevTapInterfaceStats; +virNetDevTapReattachBridge; # util/virnetdevveth.h diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index 972f3405aa..b65c26bee1 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -553,6 +553,73 @@ virNetDevTapAttachBridge(const char *tapname, } +/** + * virNetDevTapReattachBridge: + * @tapname: the tap interface name (or name template) + * @brname: the bridge name + * @macaddr: desired MAC address + * @virtPortProfile: bridge/port specific configuration + * @virtVlan: vlan tag info + * @mtu: requested MTU for port (or 0 for "default") + * @actualMTU: MTU actually set for port (after accounting for bridge's MTU) + * + * Ensures that the tap device (@tapname) is connected to the bridge + * (@brname), potentially removing it from any existing bridge that + * does not match. + * + * Returns 0 in case of success or -1 on failure + */ +int +virNetDevTapReattachBridge(const char *tapname, + const char *brname, + const virMacAddr *macaddr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + virNetDevVlanPtr virtVlan, + unsigned int mtu, + unsigned int *actualMTU) +{ + bool useOVS = false; + VIR_AUTOFREE(char *) master = NULL; + + if (virNetDevGetMaster(tapname, &master) < 0) + return -1; + + /* IFLA_MASTER for a tap on an OVS switch is always "ovs-system" */ + if (STREQ_NULLABLE(master, "ovs-system")) { + useOVS = true; + if (virNetDevOpenvswitchInterfaceGetMaster(tapname, &master) < 0) + return -1; + } + + /* Nothing more todo if we're on the right bridge already */ + if (STREQ_NULLABLE(brname, master)) + return 0; + + /* disconnect from current (incorrect) bridge, if any */ + if (master) { + int ret; + VIR_INFO("Removing %s from %s", tapname, master); + if (useOVS) + ret = virNetDevOpenvswitchRemovePort(master, tapname); + else + ret = virNetDevBridgeRemovePort(master, tapname); + if (ret < 0) + return -1; + } + + VIR_INFO("Attaching %s to %s", tapname, brname); + if (virNetDevTapAttachBridge(tapname, brname, + macaddr, vmuuid, + virtPortProfile, + virtVlan, + mtu, actualMTU) < 0) + return -1; + + return 0; +} + + /** * virNetDevTapCreateInBridgePort: * @brname: the bridge name diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h index 226122aa2c..2b3893cd37 100644 --- a/src/util/virnetdevtap.h +++ b/src/util/virnetdevtap.h @@ -71,6 +71,18 @@ virNetDevTapAttachBridge(const char *tapname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; +int +virNetDevTapReattachBridge(const char *tapname, + const char *brname, + const virMacAddr *macaddr, + const unsigned char *vmuuid, + virNetDevVPortProfilePtr virtPortProfile, + virNetDevVlanPtr virtVlan, + unsigned int mtu, + unsigned int *actualMTU) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) + ATTRIBUTE_RETURN_CHECK; + int virNetDevTapCreateInBridgePort(const char *brname, char **ifname, const virMacAddr *macaddr,