
On 01/26/2013 08:13 AM, Roman Bogorodskiy wrote:
--- src/util/virnetdevtap.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 3 deletions(-)
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index a884de1..36994fc 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -103,7 +103,7 @@ virNetDevProbeVnetHdr(int tapfd) #endif
-#ifdef TUNSETIFF +#if defined(TUNSETIFF)
Pointless churn.
@@ -230,7 +230,115 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } -#else /* ! TUNSETIFF */ +#elif defined(__FreeBSD__)
Again, what is the REAL feature that we are probing here, instead of hard-coding things to an OS probe?
+int virNetDevTapCreate(char **ifname, + int *tapfd, + unsigned int flags ATTRIBUTE_UNUSED) +{ + int s; + struct ifreq ifr; + int ret = -1; + char *newifname = NULL; + + /* As FreeBSD determines interface type by name, + * we have to create 'tap' interface first and + * then rename it to 'vnet' + */ + if ((s = virNetDevSetupControl("tap", &ifr)) < 0) + return -1; + + if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) {
Is the existence of SIOCIFCREATE2 the right feature to be probing for?
+ virReportSystemError(errno, "%s", + _("Unable to create tap device")); + goto cleanup; + } + + /* In case we were given exact interface name (e.g. 'vnetN'), + * we just rename to it. If we have format string like + * 'vnet%d', we need to find the first available name that + * matches this pattern + */ + if (strstr(*ifname, "%d") != NULL) { + int i; + for (i = 0; i <= IF_MAXUNIT; i++) { + virBuffer newname = VIR_BUFFER_INITIALIZER; + virBufferAsprintf(&newname, *ifname, i); + + if (virBufferError(&newname)) { + virBufferFreeAndReset(&newname); + virReportOOMError(); + goto cleanup; + }
virBuffer is useful for concatenation. But your use case is one-shot formatting; in which case I'd use virAsprintf instead of virBufferAsprintf: char *newname; if (virAsprintf(&newname, *ifname, i) < 0) { virReportOOMError(); goto cleanup; }
+ + if (virNetDevExists(virBufferCurrentContent(&newname)) == 0) { + newifname = strdup(virBufferContentAndReset(&newname)); + break; + }
at which point, you don't have to strdup(); newname is already the right allocated string.
+ } + if (newifname) { + VIR_FREE(*ifname); + *ifname = newifname; + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to generate new name for interface %s"), + ifr.ifr_name); + goto cleanup; + } + }
+ +int virNetDevTapDelete(const char *ifname)
int virNetDevTapDelete(const char *ifname)
+ +#else /* !defined(__FreeBSD__) */
This comment isn't quite right; it is more like: #else /* !TUNSETIFF && !__FreeBSD__ */ or whatever feature check we actually use. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org