[libvirt] [PATCHv2] network: truncate bridges' dummy tap device names to IFNAMSIZ (15) chars

Laine Stump laine at laine.org
Thu Apr 14 19:06:55 UTC 2011


(Change from V1 - define a static char[] containing the desired
prefix, and use its size to figure out how much to truncate, rather
than having a bunch of magic numbers. This also makes it simpler and
less error-prone to change the suffix if we decide to.)

This patch addresses:

   https://bugzilla.redhat.com/show_bug.cgi?id=694382

In order to give each libvirt-created bridge a fixed MAC address,
commit 5754dbd56d4738112a86776c09e810e32f7c3224, added code to create
a dummy tap device with guaranteed lowest MAC address and attach it to
the bridge. This tap device was given the name "${bridgename}-nic".
However, an interface device name must be IFNAMSIZ (15) characters or
less, so a valid ${bridgename} such as "verylongname123" (15
characters) would lead to an invalid tap device name
("verylongname123-nic" - 19 characters), and that in turn led to a
failure to bring up the network.

The solution is to shorten the part of the original name used to
generate the tap device name. However, simply truncating it is
insufficient, because the last few characters of an interface name are
often a number used to indicate one of a list of several similar
devices (for example, "verylongname123", "verylongname124", etc) and
simple truncation would lead to duplicate names (eg "verlongnam-nic"
and "verylongnam-nic"). So instead we take the first 8 characters of
$bridgename ("verylong" in the example), add on the final 3 bytes
("123"), then add "-nic" (so "verylong123-nic").  Not pretty, but it
is much more likely to generate a unique name, and is reproducible
(unlike, say, a random number).
---
 src/network/bridge_driver.c |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ea2bfd4..b108bb9 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -141,9 +141,23 @@ networkRadvdConfigFileName(const char *netname)
 static char *
 networkBridgeDummyNicName(const char *brname)
 {
+    static const char dummyNicSuffix[] = "-nic";
     char *nicname;
 
-    virAsprintf(&nicname, "%s-nic", brname);
+    if (strlen(brname) + sizeof(dummyNicSuffix) > IFNAMSIZ) {
+        /* because the length of an ifname is limited to IFNAMSIZ-1
+         * (usually 15), and we're adding 4 more characters, we must
+         * truncate the original name to 11 to fit. In order to catch
+         * a possible numeric ending (eg virbr0, virbr1, etc), we grab
+         * the first 8 and last 3 characters of the string.
+         */
+         virAsprintf(&nicname, "%.*s%s%s",
+                     /* space for last 3 chars + "-nic" + NULL */
+                     (int)(IFNAMSIZ - (3 + sizeof(dummyNicSuffix))),
+                     brname, brname + strlen(brname) - 3, dummyNicSuffix);
+    } else {
+         virAsprintf(&nicname, "%s%s", brname, dummyNicSuffix);
+    }
     return nicname;
 }
 
-- 
1.7.3.4




More information about the libvir-list mailing list