[libvirt] [PATCH 1/2] Make virNetDevSetupControl() public.

This method is useful not only in virnetdev.c. --- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 15 +++++++++++++-- src/util/virnetdev.h | 12 ++++++++++++ src/util/virnetdevmacvlan.c | 2 +- src/util/virnetdevvportprofile.c | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index cc734da..d65ecc1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1526,6 +1526,7 @@ virNetDevSetMTUFromDevice; virNetDevSetName; virNetDevSetNamespace; virNetDevSetOnline; +virNetDevSetupControl; virNetDevValidateConfig; diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index cee4001..f658c6d 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -88,11 +88,22 @@ static int virNetDevSetupControlFull(const char *ifname, } -static int virNetDevSetupControl(const char *ifname, - struct ifreq *ifr) +int +virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) { return virNetDevSetupControlFull(ifname, ifr, VIR_NETDEV_FAMILY, SOCK_DGRAM); } +#else +int +virNetDevSetupControl(const char *ifname ATTRIBUTE_UNUSED, + void *ifr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("%s is not supported on this platform"), + __func__); + return -1; +} #endif diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index bc0777c..73c267f 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -23,11 +23,23 @@ #ifndef __VIR_NETDEV_H__ # define __VIR_NETDEV_H__ +# include <config.h> +# include <net/if.h> + # include "virsocketaddr.h" # include "virnetlink.h" # include "virmacaddr.h" # include "virpci.h" +#ifdef HAVE_STRUCT_IFREQ +int virNetDevSetupControl(const char *ifname, + struct ifreq *ifr) + ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +#else +int virNetDevSetupControl(const char *ifname, + void *ifr); +#endif + int virNetDevExists(const char *brname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c index 5316520..d5d36e4 100644 --- a/src/util/virnetdevmacvlan.c +++ b/src/util/virnetdevmacvlan.c @@ -48,7 +48,7 @@ VIR_ENUM_IMPL(virNetDevMacVLanMode, VIR_NETDEV_MACVLAN_MODE_LAST, # include <sys/socket.h> # include <sys/ioctl.h> -# include <linux/if.h> +# include <net/if.h> # include <linux/if_tun.h> /* Older kernels lacked this enum value. */ diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c index 883aa46..71aae24 100644 --- a/src/util/virnetdevvportprofile.c +++ b/src/util/virnetdevvportprofile.c @@ -49,7 +49,7 @@ VIR_ENUM_IMPL(virNetDevVPortProfileOp, VIR_NETDEV_VPORT_PROFILE_OP_LAST, # include <sys/socket.h> # include <sys/ioctl.h> -# include <linux/if.h> +# include <net/if.h> # include <linux/if_tun.h> # include "virnetlink.h" -- 1.7.11.5

Implementation uses SIOCIFCREATE2 and SIOCIFDESTROY ioctls. --- src/util/virnetdevtap.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c index 75599db..468d3a8 100644 --- a/src/util/virnetdevtap.c +++ b/src/util/virnetdevtap.c @@ -263,7 +263,112 @@ cleanup: VIR_FORCE_CLOSE(fd); return ret; } -#else /* ! TUNSETIFF */ +#elif defined(SIOCIFCREATE2) && defined(SIOCIFDESTROY) +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) { + 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++) { + char *newname; + if (virAsprintf(&newname, *ifname, i) < 0) { + virReportOOMError(); + goto cleanup; + } + + if (virNetDevExists(newname) == 0) { + newifname = newname; + break; + } + } + 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; + } + } + + if (tapfd) { + char *dev_path = NULL; + if (virAsprintf(&dev_path, "/dev/%s", ifr.ifr_name) < 0) { + virReportOOMError(); + goto cleanup; + } + + if ((*tapfd = open(dev_path, O_RDWR)) < 0) { + virReportSystemError(errno, + _("Unable to open %s"), + dev_path); + VIR_FREE(dev_path); + goto cleanup; + } + + VIR_FREE(dev_path); + } + + if (virNetDevSetName(ifr.ifr_name, *ifname) == -1) { + goto cleanup; + } + + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(s); + + return ret; +} + +int virNetDevTapDelete(const char *ifname) +{ + int s; + struct ifreq ifr; + int ret = -1; + + if ((s = virNetDevSetupControl(ifname, &ifr)) < 0) + return -1; + + if (ioctl(s, SIOCIFDESTROY, &ifr) < 0) { + virReportSystemError(errno, + _("Unable to remove tap device %s"), + ifname); + goto cleanup; + } + + ret = 0; +cleanup: + VIR_FORCE_CLOSE(s); + return ret; +} + +#else int virNetDevTapCreate(char **ifname ATTRIBUTE_UNUSED, int *tapfd ATTRIBUTE_UNUSED, unsigned int flags ATTRIBUTE_UNUSED) @@ -278,7 +383,7 @@ int virNetDevTapDelete(const char *ifname ATTRIBUTE_UNUSED) _("Unable to delete TAP devices on this platform")); return -1; } -#endif /* ! TUNSETIFF */ +#endif /** -- 1.7.11.5

On 05/15/2013 11:47 PM, Roman Bogorodskiy wrote:
This method is useful not only in virnetdev.c. --- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 15 +++++++++++++-- src/util/virnetdev.h | 12 ++++++++++++ src/util/virnetdevmacvlan.c | 2 +- src/util/virnetdevvportprofile.c | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-)
+#else +int +virNetDevSetupControl(const char *ifname ATTRIBUTE_UNUSED, + void *ifr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("%s is not supported on this platform"), + __func__);
virReportSystemError is already a macro that reports the function name, so your message would include the name twice. But offhand, I can't think of any better wording to use.
+++ b/src/util/virnetdev.h @@ -23,11 +23,23 @@ #ifndef __VIR_NETDEV_H__ # define __VIR_NETDEV_H__
+# include <config.h>
Headers should never need to include <config.h>. After all, the only way to use a header is from a .c file, but the .c file should have included <config.h> prior to any other header. Looks reasonable once that is fixed up. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On Sat, May 25, 2013 at 07:07:49AM -0600, Eric Blake wrote:
On 05/15/2013 11:47 PM, Roman Bogorodskiy wrote:
This method is useful not only in virnetdev.c. --- src/libvirt_private.syms | 1 + src/util/virnetdev.c | 15 +++++++++++++-- src/util/virnetdev.h | 12 ++++++++++++ src/util/virnetdevmacvlan.c | 2 +- src/util/virnetdevvportprofile.c | 2 +- 5 files changed, 28 insertions(+), 4 deletions(-)
+#else +int +virNetDevSetupControl(const char *ifname ATTRIBUTE_UNUSED, + void *ifr ATTRIBUTE_UNUSED) +{ + virReportSystemError(ENOSYS, + _("%s is not supported on this platform"), + __func__);
virReportSystemError is already a macro that reports the function name, so your message would include the name twice. But offhand, I can't think of any better wording to use.
How about "Network device configuration is not supported on this platform" Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
participants (3)
-
Daniel P. Berrange
-
Eric Blake
-
Roman Bogorodskiy