[libvirt] [PATCH] libvirt_proxy: link with -lpthread if needed
by Eric Blake
Continuation of earlier patches to fix LIB_PTHREAD, only
triggered by ./configure --with-xen-proxy (a la autobuild.sh).
* proxy/Makefile.am (libvirt_proxy_LDADD): Add LIB_PTHREAD.
---
I'm pushing this under the obvious rule - autobuild.sh has
been broken for a few commits now. It is more fallout from
using gnulib for LIB_PTHREAD, and wasn't detected until
now because I don't use --with-xen-proxy that often.
proxy/Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/proxy/Makefile.am b/proxy/Makefile.am
index 9ea91d8..bee47d0 100644
--- a/proxy/Makefile.am
+++ b/proxy/Makefile.am
@@ -34,7 +34,7 @@ libvirt_proxy_SOURCES = libvirt_proxy.c \
@top_srcdir(a)/src/xen/xs_internal.c
libvirt_proxy_LDFLAGS = $(WARN_CFLAGS) $(XEN_LIBS)
libvirt_proxy_DEPENDENCIES =
-libvirt_proxy_LDADD = ../gnulib/lib/libgnu.la
+libvirt_proxy_LDADD = ../gnulib/lib/libgnu.la $(LIB_PTHREAD)
install-exec-hook:
chmod u+s $(DESTDIR)$(libexecdir)/libvirt_proxy
--
1.7.0.1
14 years, 7 months
[libvirt] [PATCH] node_device: udev: Fix PCI product/vendor swappage
by Cole Robinson
Product and vendor values were swapped in the XML, which made virt-manager
PCI device listing kinda useless.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
src/node_device/node_device_udev.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index bcfe991..4a9d65f 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -382,8 +382,8 @@ static int udevTranslatePCIIds(unsigned int vendor,
/* pci_get_strings returns void */
pci_get_strings(&m,
- &vendor_name,
&device_name,
+ &vendor_name,
NULL,
NULL);
--
1.6.6.1
14 years, 7 months
[libvirt] [PATCH v2] Determine the root physical interface of a given interface
by Stefan Berger
In this patch I am adding functions that help to iteratively determine
the root physical interface of a given interface. An example would be
that a macvtap device is linked to eth0.100 which in turn is linked to
eth0. Given the name or interface index of the macvtap device that is
linked to eth0.100, eth0 is found by following the links to the end. I
am using now the netlink library to parse the returned netlink messages
and for that I am making additions to configure.ac and the rpm spec file
to check for the netlink and netlink-devel packages respectively. In the
configure.ac the requirement to have the netlink library is dependent on
having macvtap.
The setup of the upcoming VEPA patches requires knowledge over which
interface to run the setup protocol. In the above case the protocol
would need to run over interface eth0 and provide the knowledge of vlan
id 100 in the protocol (see previous patch).
Changes from V1 to V2:
- replaced the constant '256' representing the space for a netlink
message with a constant
- replaced the constant '64' representing the space for a rtattr
structure with a constant
- fixed the spacings that weren't correct
- fixed M4 quoting
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
configure.ac | 24 ++++++
libvirt.spec.in | 14 +++
src/Makefile.am | 4 -
src/util/macvtap.c | 197
++++++++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 229 insertions(+), 10 deletions(-)
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -41,6 +41,9 @@
# include <linux/rtnetlink.h>
# include <linux/if_tun.h>
+# include <netlink/attr.h>
+# include <netlink/msg.h>
+
# include "util.h"
# include "memory.h"
# include "macvtap.h"
@@ -57,6 +60,9 @@
# define MACVTAP_NAME_PREFIX "macvtap"
# define MACVTAP_NAME_PATTERN "macvtap%d"
+#define MAX_NL_MESSAGE_SIZE 256
+#define MAX_RTATTR_SIZE 64
+
static int nlOpen(void)
{
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
@@ -202,10 +208,10 @@ link_add(const char *type,
int *retry)
{
int rc = 0;
- char nlmsgbuf[256];
+ char nlmsgbuf[MAX_NL_MESSAGE_SIZE] = { 0, };
struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
struct nlmsgerr *err;
- char rtattbuf[64];
+ char rtattbuf[MAX_RTATTR_SIZE];
struct rtattr *rta, *rta1, *li;
struct ifinfomsg i = { .ifi_family = AF_UNSPEC };
int ifindex;
@@ -217,8 +223,6 @@ link_add(const char *type,
*retry = 0;
- memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
-
nlInit(nlm, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
RTM_NEWLINK);
if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i)))
@@ -347,17 +351,15 @@ static int
link_del(const char *name)
{
int rc = 0;
- char nlmsgbuf[256];
+ char nlmsgbuf[MAX_NL_MESSAGE_SIZE] = { 0, };
struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
struct nlmsgerr *err;
- char rtattbuf[64];
+ char rtattbuf[MAX_RTATTR_SIZE];
struct rtattr *rta;
struct ifinfomsg ifinfo = { .ifi_family = AF_UNSPEC };
char *recvbuf = NULL;
int recvbuflen;
- memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
-
nlInit(nlm, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL,
RTM_DELLINK);
if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
@@ -421,6 +423,185 @@ buffer_too_small:
}
+static struct nla_policy ifla_policy[IFLA_MAX + 1] =
+{
+ [IFLA_IFNAME] = { .type = NLA_STRING },
+ [IFLA_LINK] = { .type = NLA_U32 },
+};
+
+
+static int
+link_dump(int ifindex, const char *ifname, struct nlattr **tb,
+ char **recvbuf)
+{
+ int rc = 0;
+ char nlmsgbuf[MAX_NL_MESSAGE_SIZE] = { 0, };
+ struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+ struct nlmsgerr *err;
+ char rtattbuf[MAX_RTATTR_SIZE];
+ struct rtattr *rta;
+ struct ifinfomsg i = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = ifindex
+ };
+ int recvbuflen;
+
+ *recvbuf = NULL;
+
+ nlInit(nlm, NLM_F_REQUEST, RTM_GETLINK);
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i)))
+ goto buffer_too_small;
+
+ if (ifindex < 0 && ifname != NULL) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
+ ifname, strlen(ifname) + 1);
+ if (!rta)
+ goto buffer_too_small;
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ if (nlComm(nlm, recvbuf, &recvbuflen) < 0)
+ return -1;
+
+ if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)*recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ switch (-err->error) {
+ case 0:
+ break;
+
+ default:
+ virReportSystemError(-err->error,
+ _("error dumping %d interface"),
+ ifindex);
+ rc = -1;
+ }
+ break;
+
+ case GENL_ID_CTRL:
+ case NLMSG_DONE:
+ if (nlmsg_parse(resp, sizeof(struct ifinfomsg),
+ tb, IFLA_MAX, ifla_policy)) {
+ goto malformed_resp;
+ }
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+ if (rc != 0)
+ VIR_FREE(*recvbuf);
+
+ return rc;
+
+malformed_resp:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(*recvbuf);
+ return -1;
+
+buffer_too_small:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("internal buffer is too small"));
+ return -1;
+}
+
+
+/* TODO: move this into interface.c after moving netlink functions into
+ * utils dir
+ */
+/**
+ * ifaceGetNthParent
+ *
+ * @ifindex : the index of the interface or -1 if ifname is given
+ * @ifname : the name of the interface; ignored if ifindex is valid
+ * @nthParent : the nth parent interface to get
+ * @rootifname : pointer to buffer of size IFNAMSIZ
+ * @nth : the nth parent that is actually returned; if for example
eth0.100
+ * was given and the 100th parent is to be returned, then eth0
will
+ * most likely be returned with nth set to 1 since the chain
does
+ * not have more interfaces
+ *
+ * Get the nth parent interface of the given interface. 0 is the
interface
+ * itself.
+ *
+ * Return 0 on success, != 0 otherwise
+ */
+static int
+ifaceGetNthParent(int ifindex, const char *ifname, unsigned int
nthParent,
+ char *rootifname, unsigned int *nth)
+{
+ int rc;
+ struct nlattr *tb[IFLA_MAX + 1];
+ char *recvbuf = NULL;
+ bool end = false;
+ unsigned int i = 0;
+
+ while (!end && i <= nthParent) {
+ rc = link_dump(ifindex, ifname, tb, &recvbuf);
+ if (rc)
+ break;
+
+ if (tb[IFLA_IFNAME]) {
+ if (!virStrcpy(rootifname,
(char*)RTA_DATA(tb[IFLA_IFNAME]),
+ IFNAMSIZ)) {
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("buffer for root interface name is too
small"));
+ VIR_FREE(recvbuf);
+ return 1;
+ }
+ }
+
+ if (tb[IFLA_LINK]) {
+ ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]);
+ ifname = NULL;
+ } else
+ end = true;
+
+ VIR_FREE(recvbuf);
+
+ i++;
+ }
+
+ if (nth)
+ *nth = i - 1;
+
+ return rc;
+}
+
+
+/**
+ * ifaceGetRootIface
+ *
+ * @ifindex : the index of the interface or -1 if ifname is given
+ * @ifname : the name of the interface; ignored if ifindex is valid
+ * @rootifname : pointer to buffer of size IFNAMSIZ
+ *
+ * Get the root interface of a given interface, i.e., if macvtap
+ * is linked to eth0.100, it will return eth0.
+ *
+ * Return 0 on success, != 0 otherwise
+ */
+static int
+ifaceGetRootIface(int ifindex, const char *ifname,
+ char *rootifname)
+{
+ return ifaceGetNthParent(ifindex, ifname, ~0, rootifname, NULL);
+}
+
+
/* Open the macvtap's tap device.
* @ifname: Name of the macvtap interface
* @retries : Number of retries in case udev for example may need to be
Index: libvirt-acl/configure.ac
===================================================================
--- libvirt-acl.orig/configure.ac
+++ libvirt-acl/configure.ac
@@ -42,6 +42,7 @@ HAL_REQUIRED=0.5.0
DEVMAPPER_REQUIRED=1.0.0
LIBCURL_REQUIRED="7.18.0"
LIBPCAP_REQUIRED="1.0.0"
+LIBNL_REQUIRED="1.1"
dnl Checks for C compiler.
AC_PROG_CC
@@ -2005,6 +2006,24 @@ fi
AM_CONDITIONAL([WITH_MACVTAP], [test "$with_macvtap" = "yes"])
+dnl netlink library
+
+LIBNL_CFLAGS=""
+LIBNL_LIBS=""
+
+if test "$with_macvtap" = "yes"; then
+ PKG_CHECK_MODULES([LIBNL], [libnl-1 >= $LIBNL_REQUIRED], [
+ ], [
+ AC_MSG_ERROR([libnl >= $LIBNL_REQUIRED is required for macvtap
support])
+ ])
+fi
+
+AC_SUBST([LIBNL_CFLAGS])
+AC_SUBST([LIBNL_LIBS])
+
+
+
+
# Only COPYING.LIB is under version control, yet COPYING
# is included as part of the distribution tarball.
# Copy one to the other, but only if this is a srcdir-build.
@@ -2183,6 +2202,11 @@ AC_MSG_NOTICE([ pcap: $LIBPCAP_CFLAGS
else
AC_MSG_NOTICE([ pcap: no])
fi
+if test "$with_macvtap" = "yes" ; then
+AC_MSG_NOTICE([ nl: $LIBNL_CFLAGS $LIBNL_LIBS])
+else
+AC_MSG_NOTICE([ nl: no])
+fi
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Test suite])
AC_MSG_NOTICE([])
Index: libvirt-acl/libvirt.spec.in
===================================================================
--- libvirt-acl.orig/libvirt.spec.in
+++ libvirt-acl/libvirt.spec.in
@@ -63,6 +63,7 @@
%define with_yajl 0%{!?_without_yajl:0}
%define with_nwfilter 0%{!?_without_nwfilter:0}
%define with_libpcap 0%{!?_without_libpcap:0}
+%define with_macvtap 0%{!?_without_macvtap:0}
# Non-server/HV driver defaults which are always enabled
%define with_python 0%{!?_without_python:1}
@@ -153,6 +154,11 @@
%if %{with_qemu}
%define with_nwfilter 0%{!?_without_nwfilter:%{server_drivers}}
%define with_libpcap 0%{!?_without_libpcap:%{server_drivers}}
+%define with_macvtap 0%{!?_without_macvtap:%{server_drivers}}
+%endif
+
+%if %{with_macvtap}
+%define with_libnl 1
%endif
# Force QEMU to run as non-root
@@ -282,6 +288,9 @@ BuildRequires: yajl-devel
%if %{with_libpcap}
BuildRequires: libpcap-devel
%endif
+%if %{with_libnl}
+BuildRequires: libnl-devel
+%endif
%if %{with_avahi}
BuildRequires: avahi-devel
%endif
@@ -531,6 +540,10 @@ of recent versions of Linux (and other O
%define _without_libpcap --without-libpcap
%endif
+%if ! %{with_macvtap}
+%define _without_macvtap --without-macvtap
+%endif
+
%configure %{?_without_xen} \
%{?_without_qemu} \
%{?_without_openvz} \
@@ -560,6 +573,7 @@ of recent versions of Linux (and other O
%{?_without_udev} \
%{?_without_yajl} \
%{?_without_libpcap} \
+ %{?_without_macvtap} \
--with-qemu-user=%{qemu_user} \
--with-qemu-group=%{qemu_group} \
--with-init-script=redhat \
Index: libvirt-acl/src/Makefile.am
===================================================================
--- libvirt-acl.orig/src/Makefile.am
+++ libvirt-acl/src/Makefile.am
@@ -973,7 +973,7 @@ libvirt_la_LDFLAGS = $(VERSION_SCRIPT_FL
$(COVERAGE_CFLAGS:-f%=-Wc,-f%) \
$(CYGWIN_EXTRA_LDFLAGS) $(MINGW_EXTRA_LDFLAGS)
libvirt_la_LIBADD += $(LIBXML_LIBS) \
- $(LIBPCAP_LIBS) \
+ $(LIBPCAP_LIBS) $(LIBNL_LIBS) \
$(DRIVER_MODULE_LIBS) \
$(CYGWIN_EXTRA_LIBADD) ../gnulib/lib/libgnu.la
libvirt_la_CFLAGS = $(COVERAGE_CFLAGS) -DIN_LIBVIRT
@@ -1027,7 +1027,7 @@ libvirt_lxc_SOURCES = \
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS)
libvirt_lxc_LDADD = $(CAPNG_LIBS) $(YAJL_LIBS) \
$(LIBXML_LIBS) $(NUMACTL_LIBS) $(LIB_PTHREAD) \
- ../gnulib/lib/libgnu.la
+ $(LIBNL_LIBS) ../gnulib/lib/libgnu.la
libvirt_lxc_CFLAGS = \
$(LIBPARTED_CFLAGS) \
$(NUMACTL_CFLAGS) \
14 years, 7 months
[libvirt] [PATCH] tests: adjust copyrights on scripts: s/FSF/Red Hat/
by Jim Meyering
FYI, just pushed.
I ran this command:
cd tests && grep -l 'Copy.*Free.Sof' * |xargs perl -pi -e \
's/Copyright \(C\) (.*) Free Software Foundation,/Copyright (C) $1 Red Hat,/'
>From c5be8bcb8f4b72a39481eeef58d601ec585e0c6f Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Tue, 11 May 2010 16:43:07 +0200
Subject: [PATCH] tests: adjust copyrights on scripts: s/FSF/Red Hat/
* tests/cpuset: Change copyright holder from FSF to Red Hat, Inc.
* tests/read-bufsiz: Likewise.
* tests/read-non-seekable: Likewise.
* tests/start: Likewise.
* tests/undefine: Likewise.
* tests/vcpupin: Likewise.
* tests/virsh-all: Likewise.
* tests/virsh-synopsis: Likewise.
---
tests/cpuset | 2 +-
tests/read-bufsiz | 2 +-
tests/read-non-seekable | 2 +-
tests/start | 2 +-
tests/undefine | 2 +-
tests/vcpupin | 2 +-
tests/virsh-all | 2 +-
tests/virsh-synopsis | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/tests/cpuset b/tests/cpuset
index 89c19e0..3c48f0a 100755
--- a/tests/cpuset
+++ b/tests/cpuset
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that defining with an invalid vCPU cpuset elicits a diagnostic
-# Copyright (C) 2008-2009 Free Software Foundation, Inc.
+# Copyright (C) 2008-2009 Red Hat, Inc.
# 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
diff --git a/tests/read-bufsiz b/tests/read-bufsiz
index f4f8f19..3ebc135 100755
--- a/tests/read-bufsiz
+++ b/tests/read-bufsiz
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that reading a file larger than BUFSIZ works
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008 Red Hat, Inc.
# 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
diff --git a/tests/read-non-seekable b/tests/read-non-seekable
index 59c2389..1aed286 100755
--- a/tests/read-non-seekable
+++ b/tests/read-non-seekable
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that certain file-reading commands can handle non-seekable files
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008 Red Hat, Inc.
# 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
diff --git a/tests/start b/tests/start
index 930a6d9..df92a36 100755
--- a/tests/start
+++ b/tests/start
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that virsh start works properly
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008 Red Hat, Inc.
# 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
diff --git a/tests/undefine b/tests/undefine
index 48b0ad9..d9efbf7 100755
--- a/tests/undefine
+++ b/tests/undefine
@@ -1,7 +1,7 @@
#!/bin/sh
# exercise virsh's "undefine" command
-# Copyright (C) 2008-2009 Free Software Foundation, Inc.
+# Copyright (C) 2008-2009 Red Hat, Inc.
# 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
diff --git a/tests/vcpupin b/tests/vcpupin
index a72ad4c..36dd093 100755
--- a/tests/vcpupin
+++ b/tests/vcpupin
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that an invalid CPU spec elicits a diagnostic
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008 Red Hat, Inc.
# 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
diff --git a/tests/virsh-all b/tests/virsh-all
index f1eb82c..baec161 100755
--- a/tests/virsh-all
+++ b/tests/virsh-all
@@ -1,7 +1,7 @@
#!/bin/sh
# blindly run each and every command listed by "virsh help"
-# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 2008, 2009 Red Hat, Inc.
# 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
diff --git a/tests/virsh-synopsis b/tests/virsh-synopsis
index d72e887..e60aeb5 100755
--- a/tests/virsh-synopsis
+++ b/tests/virsh-synopsis
@@ -1,7 +1,7 @@
#!/bin/sh
# ensure that each command's help "SYNOPSIS" line starts with the command name
-# Copyright (C) 2008 Free Software Foundation, Inc.
+# Copyright (C) 2008 Red Hat, Inc.
# 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
--
1.7.1.189.g07419
14 years, 7 months
[libvirt] [PATCH] storage_encryption: silence clang warning
by Eric Blake
For printf("%*s",foo,bar), clang complains if foo is not int:
warning: field width should have type 'int', but argument has
type 'unsigned int' [-Wformat]
* src/conf/storage_encryption_conf.c
(virStorageEncryptionSecretFormat, virStorageEncryptionFormat):
Use correct type.
---
src/conf/storage_encryption_conf.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c
index 7a64050..8f29492 100644
--- a/src/conf/storage_encryption_conf.c
+++ b/src/conf/storage_encryption_conf.c
@@ -1,7 +1,7 @@
/*
* storage_encryption_conf.c: volume encryption information
*
- * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright (C) 2009-2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -216,7 +216,7 @@ virStorageEncryptionParseNode(xmlDocPtr xml, xmlNodePtr root)
static int
virStorageEncryptionSecretFormat(virBufferPtr buf,
virStorageEncryptionSecretPtr secret,
- unsigned int indent)
+ int indent)
{
const char *type;
char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -249,14 +249,15 @@ virStorageEncryptionFormat(virBufferPtr buf,
return -1;
}
virBufferVSprintf(buf, "%*s<encryption format='%s'>\n",
- indent, "", format);
+ (int) indent, "", format);
for (i = 0; i < enc->nsecrets; i++) {
- if (virStorageEncryptionSecretFormat(buf, enc->secrets[i], indent + 2) < 0)
+ if (virStorageEncryptionSecretFormat(buf, enc->secrets[i],
+ indent + 2) < 0)
return -1;
}
- virBufferVSprintf(buf, "%*s</encryption>\n", indent, "");
+ virBufferVSprintf(buf, "%*s</encryption>\n", (int) indent, "");
return 0;
}
--
1.6.6.1
14 years, 7 months
[libvirt] [PATCH] vepa: parsing for 802.1Qb{g|h} XML
by Stefan Berger
Below is David Alan's original patch with lots of changes.
In particular, it now parses the following XML and stored the data
internally. No sending of netlink messages has been implemented here.
<interface type='direct'>
<source dev='static' mode='vepa'/>
<model type='virtio'/>
<vsi managerid='12' typeid='0x123456' typeidversion='1'
instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f' />
<filterref filter='clean-traffic'/>
</interface>
<interface type='direct'>
<source dev='static' mode='vepa'/>
<model type='virtio'/>
<vsi profileid='my_profile'/>
</interface>
I'd suggest to use this patch as a base for sending out netlink
messages.
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
>From a945107f047c7cd71f9c1b74fd74c47d8cdc3670 Mon Sep 17 00:00:00 2001
From: David Allan <dallan(a)redhat.com>
Date: Fri, 12 Mar 2010 13:25:04 -0500
Subject: [PATCH 1/1] POC of port profile id support
* Modified schema per DanPB's feedback
* Added test for modified schema
---
docs/schemas/domain.rng | 57 +++++++++++++++++++
src/conf/domain_conf.c | 97
+++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 31 ++++++++++
src/qemu/qemu_conf.c | 11 ---
src/qemu/qemu_conf.h | 2
src/qemu/qemu_driver.c | 14 +---
src/util/macvtap.c | 89
+++++++++++++++++++++++++-----
src/util/macvtap.h | 7 +-
tests/domainschemadata/portprofile.xml | 22 +++++++
9 files changed, 292 insertions(+), 38 deletions(-)
create mode 100644 tests/domainschemadata/portprofile.xml
Index: libvirt-acl/docs/schemas/domain.rng
===================================================================
--- libvirt-acl.orig/docs/schemas/domain.rng
+++ libvirt-acl/docs/schemas/domain.rng
@@ -817,6 +817,9 @@
</optional>
<empty/>
</element>
+ <optional>
+ <ref name="vsiProfile"/>
+ </optional>
<ref name="interface-options"/>
</interleave>
</group>
@@ -902,6 +905,33 @@
</optional>
</interleave>
</define>
+ <define name="vsiProfile">
+ <choice>
+ <group>
+ <element name="vsi">
+ <attribute name="managerid">
+ <ref name="uint8range"/>
+ </attribute>
+ <attribute name="typeid">
+ <ref name="uint24range"/>
+ </attribute>
+ <attribute name="typeidversion">
+ <ref name="uint8range"/>
+ </attribute>
+ <attribute name="instanceid">
+ <ref name="UUID"/>
+ </attribute>
+ </element>
+ </group>
+ <group>
+ <element name="vsi">
+ <attribute name="profileid">
+ <ref name="vsiProfileID"/>
+ </attribute>
+ </element>
+ </group>
+ </choice>
+ </define>
<!--
An emulator description is just a path to the binary used for the
task
-->
@@ -1769,4 +1799,31 @@
<param name="pattern">[a-zA-Z0-9_\.:]+</param>
</data>
</define>
+ <define name="uint8range">
+ <choice>
+ <data type="string">
+ <param name="pattern">0x[0-9a-fA-F]{1,2}</param>
+ </data>
+ <data type="int">
+ <param name="minInclusive">0</param>
+ <param name="maxInclusive">255</param>
+ </data>
+ </choice>
+ </define>
+ <define name="uint24range">
+ <choice>
+ <data type="string">
+ <param name="pattern">0x[0-9a-fA-F]{1,6}</param>
+ </data>
+ <data type="int">
+ <param name="minInclusive">0</param>
+ <param name="maxInclusive">16777215</param>
+ </data>
+ </choice>
+ </define>
+ <define name="vsiProfileID">
+ <data type="string">
+ <param name="maxLength">39</param>
+ </data>
+ </define>
</grammar>
Index: libvirt-acl/src/conf/domain_conf.c
===================================================================
--- libvirt-acl.orig/src/conf/domain_conf.c
+++ libvirt-acl/src/conf/domain_conf.c
@@ -1831,7 +1831,13 @@ virDomainNetDefParseXML(virCapsPtr caps,
char *internal = NULL;
char *devaddr = NULL;
char *mode = NULL;
+ char *vsiManagerID = NULL;
+ char *vsiTypeID = NULL;
+ char *vsiTypeIDVersion = NULL;
+ char *vsiInstanceID = NULL;
+ char *vsiProfileID = NULL;
virNWFilterHashTablePtr filterparams = NULL;
+ virVSIProfileDefPtr vsi;
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
@@ -1873,6 +1879,20 @@ virDomainNetDefParseXML(virCapsPtr caps,
xmlStrEqual(cur->name, BAD_CAST "source")) {
dev = virXMLPropString(cur, "dev");
mode = virXMLPropString(cur, "mode");
+ } else if ((vsiManagerID == NULL) &&
+ (vsiTypeID == NULL) &&
+ (vsiTypeIDVersion == NULL) &&
+ (vsiInstanceID == NULL) &&
+ (vsiProfileID == NULL) &&
+ (def->type == VIR_DOMAIN_NET_TYPE_DIRECT) &&
+ xmlStrEqual(cur->name, BAD_CAST "vsi")) {
+ vsiManagerID = virXMLPropString(cur, "managerid");
+ vsiTypeID = virXMLPropString(cur, "typeid");
+ vsiTypeIDVersion = virXMLPropString(cur,
"typeidversion");
+ vsiInstanceID = virXMLPropString(cur, "instanceid");
+#ifdef IFLA_VF_PORT_PROFILE_MAX
+ vsiProfileID = virXMLPropString(cur, "profileid");
+#endif
} else if ((network == NULL) &&
((def->type == VIR_DOMAIN_NET_TYPE_SERVER) ||
(def->type == VIR_DOMAIN_NET_TYPE_CLIENT) ||
@@ -2049,6 +2069,51 @@ virDomainNetDefParseXML(virCapsPtr caps,
} else
def->data.direct.mode =
VIR_DOMAIN_NETDEV_MACVTAP_MODE_VEPA;
+ vsi = &def->data.direct.vsiProfile;
+
+#ifdef IFLA_VF_PORT_PROFILE_MAX
+ if (vsiProfileID != NULL) {
+ if (virStrcpyStatic(vsi->u.vsi8021Qbh.profileID,
+ vsiProfileID) != NULL) {
+ vsi->vsiType = VIR_VSI_8021QBH;
+ break;
+ }
+ }
+#endif
+
+ while (vsiManagerID != NULL && vsiTypeID != NULL &&
+ vsiTypeIDVersion != NULL && vsiInstanceID != NULL) {
+ unsigned int val;
+
+ if ((virStrToLong_ui(vsiManagerID, NULL, 10, &val) &&
+ virStrToLong_ui(vsiManagerID, NULL, 16, &val) ) ||
+ val > 0xff)
+ break;
+
+ vsi->u.vsi8021Qbg.managerID = (uint8_t)val;
+
+ if ((virStrToLong_ui(vsiTypeID, NULL, 10, &val) &&
+ virStrToLong_ui(vsiTypeID, NULL, 16, &val) ) ||
+ val > 0xffffff)
+ break;
+
+ vsi->u.vsi8021Qbg.typeID = (uint32_t)val;
+
+ if ((virStrToLong_ui(vsiTypeIDVersion, NULL, 10, &val) &&
+ virStrToLong_ui(vsiTypeIDVersion, NULL, 16, &val) )
||
+ val > 0xff)
+ break;
+
+ vsi->u.vsi8021Qbg.typeIDVersion = (uint8_t)val;
+
+ if (virUUIDParse(vsiInstanceID,
+
def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID))
+ break;
+
+ vsi->vsiType = VIR_VSI_8021QBG;
+ break;
+ }
+
def->data.direct.linkdev = dev;
dev = NULL;
@@ -2114,6 +2179,11 @@ cleanup:
VIR_FREE(internal);
VIR_FREE(devaddr);
VIR_FREE(mode);
+ VIR_FREE(vsiManagerID);
+ VIR_FREE(vsiTypeID);
+ VIR_FREE(vsiTypeIDVersion);
+ VIR_FREE(vsiInstanceID);
+ VIR_FREE(vsiProfileID);
virNWFilterHashTableFree(filterparams);
return def;
@@ -5076,6 +5146,8 @@ virDomainNetDefFormat(virBufferPtr buf,
{
const char *type = virDomainNetTypeToString(def->type);
char *attrs;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virVSIProfileDefPtr vsi;
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -5141,6 +5213,31 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferVSprintf(buf, " mode='%s'",
virDomainNetdevMacvtapTypeToString(def->data.direct.mode));
virBufferAddLit(buf, "/>\n");
+ vsi = &def->data.direct.vsiProfile;
+ switch (vsi->vsiType) {
+ case VIR_VSI_INVALID:
+ break;
+
+ case VIR_VSI_8021QBG:
+
virUUIDFormat(def->data.direct.vsiProfile.u.vsi8021Qbg.instanceID,
+ uuidstr);
+ virBufferVSprintf(buf,
+ " <vsi managerid='%d' typeid='%d' "
+ "typeidversion='%d' instanceid='%s'/>\n",
+ vsi->u.vsi8021Qbg.managerID,
+ vsi->u.vsi8021Qbg.typeID,
+ vsi->u.vsi8021Qbg.typeIDVersion,
+ uuidstr);
+ break;
+
+#ifdef IFLA_VF_PORT_PROFILE_MAX
+ case VIR_VSI_8021QBH:
+ virBufferVSprintf(buf,
+ " <vsi profileid='%s'/>\n",
+ vsi->u.vsi8021Qbh.profileID);
+ break;
+#endif
+ }
break;
case VIR_DOMAIN_NET_TYPE_USER:
Index: libvirt-acl/src/conf/domain_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/domain_conf.h
+++ libvirt-acl/src/conf/domain_conf.h
@@ -259,6 +259,36 @@ enum virDomainNetdevMacvtapType {
};
+#define IFLA_VF_PORT_PROFILE_MAX 40
+enum virVSIType {
+ VIR_VSI_INVALID,
+ VIR_VSI_8021QBG,
+#ifdef IFLA_VF_PORT_PROFILE_MAX
+ VIR_VSI_8021QBH,
+#endif
+};
+
+/* profile data for macvtap (VEPA) */
+typedef struct _virVSIProfileDef virVSIProfileDef;
+typedef virVSIProfileDef *virVSIProfileDefPtr;
+struct _virVSIProfileDef {
+ enum virVSIType vsiType;
+ union {
+ struct {
+ uint8_t managerID;
+ uint32_t typeID; // 24 bit valid
+ uint8_t typeIDVersion;
+ unsigned char instanceID[VIR_UUID_BUFLEN];
+ } vsi8021Qbg;
+#ifdef IFLA_VF_PORT_PROFILE_MAX
+ struct {
+ char profileID[IFLA_VF_PORT_PROFILE_MAX];
+ } vsi8021Qbh;
+#endif
+ } u;
+};
+
+
/* Stores the virtual network interface configuration */
typedef struct _virDomainNetDef virDomainNetDef;
typedef virDomainNetDef *virDomainNetDefPtr;
@@ -290,6 +320,7 @@ struct _virDomainNetDef {
struct {
char *linkdev;
int mode;
+ virVSIProfileDef vsiProfile;
} direct;
} data;
char *ifname;
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -43,6 +43,7 @@
# include "util.h"
# include "memory.h"
+# include "logging.h"
# include "macvtap.h"
# include "interface.h"
# include "conf/domain_conf.h"
@@ -57,6 +58,13 @@
# define MACVTAP_NAME_PREFIX "macvtap"
# define MACVTAP_NAME_PATTERN "macvtap%d"
+
+# define PREASSOCIATE 0x00
+# define PREASSOCIATE_WITH_RESOURCE_RESERVATION 0x01
+# define ASSOCIATE 0x02
+# define DEASSOCIATE 0x03
+
+
static int nlOpen(void)
{
int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
@@ -569,6 +577,45 @@ configMacvtapTap(int tapfd, int vnet_hdr
}
+static int
+setPortProfileId(const char *linkdev ATTRIBUTE_UNUSED,
+ unsigned char *mac ATTRIBUTE_UNUSED,
+ int mode ATTRIBUTE_UNUSED,
+ const virVSIProfileDefPtr profile ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+associatePortProfileId(const char *linkdev,
+ unsigned char *mac,
+ int mode,
+ const virVSIProfileDefPtr profile)
+{
+ VIR_DEBUG("Associating port profile '%p' on link device '%s' mode %
d ",
+ profile, linkdev, mode);
+
+ return setPortProfileId(linkdev,
+ mac,
+ ASSOCIATE,
+ profile);
+}
+
+
+static int
+disassociatePortProfileId(const char *linkdev,
+ unsigned char *mac,
+ const virVSIProfileDefPtr profile)
+{
+ VIR_DEBUG("Disassociating port profile id '%p' on link device '%s'
",
+ profile, linkdev);
+
+ return setPortProfileId(linkdev,
+ mac,
+ DEASSOCIATE,
+ profile);
+}
+
/**
* openMacvtapTap:
* Create an instance of a macvtap device and open its tap character
@@ -589,9 +636,7 @@ configMacvtapTap(int tapfd, int vnet_hdr
*/
int
openMacvtapTap(const char *tgifname,
- const unsigned char *macaddress,
- const char *linkdev,
- int mode,
+ virDomainNetDefPtr net,
char **res_ifname,
int vnet_hdr)
{
@@ -599,7 +644,7 @@ openMacvtapTap(const char *tgifname,
int c, rc;
char ifname[IFNAMSIZ];
int retries, do_retry = 0;
- uint32_t macvtapMode = macvtapModeFromInt(mode);
+ uint32_t macvtapMode = macvtapModeFromInt(net->data.direct.mode);
const char *cr_ifname;
int ifindex;
@@ -616,7 +661,7 @@ openMacvtapTap(const char *tgifname,
return -1;
}
cr_ifname = tgifname;
- rc = link_add(type, macaddress, 6, tgifname, linkdev,
+ rc = link_add(type, net->mac, 6, tgifname,
net->data.direct.linkdev,
macvtapMode, &do_retry);
if (rc)
return -1;
@@ -626,7 +671,8 @@ create_name:
for (c = 0; c < 8192; c++) {
snprintf(ifname, sizeof(ifname), MACVTAP_NAME_PATTERN, c);
if (ifaceGetIndex(false, ifname, &ifindex) == ENODEV) {
- rc = link_add(type, macaddress, 6, ifname, linkdev,
+ rc = link_add(type, net->mac, 6, ifname,
+ net->data.direct.linkdev,
macvtapMode, &do_retry);
if (rc == 0)
break;
@@ -639,6 +685,13 @@ create_name:
cr_ifname = ifname;
}
+ rc = associatePortProfileId(net->data.direct.linkdev,
+ net->mac,
+ net->data.direct.mode,
+ &net->data.direct.vsiProfile);
+ if (rc != 0)
+ goto link_del_exit;
+
rc = ifaceUp(cr_ifname);
if (rc != 0) {
virReportSystemError(errno,
@@ -647,7 +700,7 @@ create_name:
"MAC address"),
cr_ifname);
rc = -1;
- goto link_del_exit;
+ goto disassociate_exit;
}
rc = openTap(cr_ifname, 10);
@@ -656,14 +709,19 @@ create_name:
if (configMacvtapTap(rc, vnet_hdr) < 0) {
close(rc);
rc = -1;
- goto link_del_exit;
+ goto disassociate_exit;
}
*res_ifname = strdup(cr_ifname);
} else
- goto link_del_exit;
+ goto disassociate_exit;
return rc;
+disassociate_exit:
+ disassociatePortProfileId(net->data.direct.linkdev,
+ net->mac,
+ &net->data.direct.vsiProfile);
+
link_del_exit:
link_del(cr_ifname);
@@ -672,15 +730,20 @@ link_del_exit:
/**
- * delMacvtapByName:
- * @ifname : The name of the macvtap interface
+ * delMacvtap:
+ * @net: pointer to virDomainNetDef object
*
* Delete an interface given its name.
*/
void
-delMacvtap(const char *ifname)
+delMacvtap(virDomainNetDefPtr net)
{
- link_del(ifname);
+ if (net->ifname) {
+ disassociatePortProfileId(net->data.direct.linkdev,
+ net->mac,
+ &net->data.direct.vsiProfile);
+ link_del(net->ifname);
+ }
}
#endif
Index: libvirt-acl/src/util/macvtap.h
===================================================================
--- libvirt-acl.orig/src/util/macvtap.h
+++ libvirt-acl/src/util/macvtap.h
@@ -27,15 +27,14 @@
# if defined(WITH_MACVTAP)
# include "internal.h"
+# include "conf/domain_conf.h"
int openMacvtapTap(const char *ifname,
- const unsigned char *macaddress,
- const char *linkdev,
- int mode,
+ virDomainNetDefPtr net,
char **res_ifname,
int vnet_hdr);
-void delMacvtap(const char *ifname);
+void delMacvtap(virDomainNetDefPtr net);
# endif /* WITH_MACVTAP */
Index: libvirt-acl/tests/domainschemadata/portprofile.xml
===================================================================
--- /dev/null
+++ libvirt-acl/tests/domainschemadata/portprofile.xml
@@ -0,0 +1,27 @@
+<domain type='lxc'>
+ <name>portprofile</name>
+ <uuid>00000000-0000-0000-0000-000000000000</uuid>
+ <memory>1048576</memory>
+ <os>
+ <type>exe</type>
+ <init>/sh</init>
+ </os>
+ <devices>
+ <interface type='direct'>
+ <source dev='eth0' mode='vepa'/>
+ <vsi managerid='12' typeid='1193046' typeidversion='1'
+ instanceid='fa9b7fff-b0a0-4893-8e0e-beef4ff18f8f'/>
+ </interface>
+ <interface type='direct'>
+ <source dev='eth0' mode='vepa'/>
+ <vsi profileid='my_profile'/>
+ </interface>
+ <interface type='direct'>
+ <source dev='eth0' mode='vepa'/>
+ <vsi/>
+ </interface>
+ <interface type='direct'>
+ <source dev='eth0' mode='vepa'/>
+ </interface>
+ </devices>
+</domain>
Index: libvirt-acl/src/qemu/qemu_conf.h
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_conf.h
+++ libvirt-acl/src/qemu/qemu_conf.h
@@ -271,8 +271,6 @@ qemudOpenVhostNet(virDomainNetDefPtr net
int qemudPhysIfaceConnect(virConnectPtr conn,
struct qemud_driver *driver,
virDomainNetDefPtr net,
- char *linkdev,
- int brmode,
unsigned long long qemuCmdFlags);
int qemudProbeMachineTypes (const char *binary,
Index: libvirt-acl/src/qemu/qemu_driver.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_driver.c
+++ libvirt-acl/src/qemu/qemu_driver.c
@@ -3585,10 +3585,8 @@ static void qemudShutdownVMDaemon(struct
def = vm->def;
for (i = 0; i < def->nnets; i++) {
virDomainNetDefPtr net = def->nets[i];
- if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
- if (net->ifname)
- delMacvtap(net->ifname);
- }
+ if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT)
+ delMacvtap(net);
}
#endif
@@ -7175,8 +7173,6 @@ static int qemudDomainAttachNetDevice(vi
}
if ((tapfd = qemudPhysIfaceConnect(conn, driver, net,
- net->data.direct.linkdev,
- net->data.direct.mode,
qemuCmdFlags)) < 0)
return -1;
}
@@ -8146,10 +8142,8 @@ qemudDomainDetachNetDevice(struct qemud_
virNWFilterTearNWFilter(detach);
#if WITH_MACVTAP
- if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
- if (detach->ifname)
- delMacvtap(detach->ifname);
- }
+ if (detach->type == VIR_DOMAIN_NET_TYPE_DIRECT)
+ delMacvtap(detach);
#endif
if ((driver->macFilter) && (detach->ifname != NULL)) {
Index: libvirt-acl/src/qemu/qemu_conf.c
===================================================================
--- libvirt-acl.orig/src/qemu/qemu_conf.c
+++ libvirt-acl/src/qemu/qemu_conf.c
@@ -1465,8 +1465,6 @@ int
qemudPhysIfaceConnect(virConnectPtr conn,
struct qemud_driver *driver,
virDomainNetDefPtr net,
- char *linkdev,
- int brmode,
unsigned long long qemuCmdFlags)
{
int rc;
@@ -1479,8 +1477,7 @@ qemudPhysIfaceConnect(virConnectPtr conn
net->model && STREQ(net->model, "virtio"))
vnet_hdr = 1;
- rc = openMacvtapTap(net->ifname, net->mac, linkdev, brmode,
- &res_ifname, vnet_hdr);
+ rc = openMacvtapTap(net->ifname, net, &res_ifname, vnet_hdr);
if (rc >= 0) {
VIR_FREE(net->ifname);
net->ifname = res_ifname;
@@ -1500,15 +1497,13 @@ qemudPhysIfaceConnect(virConnectPtr conn
if (err) {
close(rc);
rc = -1;
- delMacvtap(net->ifname);
+ delMacvtap(net);
}
}
}
#else
(void)conn;
(void)net;
- (void)linkdev;
- (void)brmode;
(void)qemuCmdFlags;
(void)driver;
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -4130,8 +4125,6 @@ int qemudBuildCommandLine(virConnectPtr
goto no_memory;
} else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
int tapfd = qemudPhysIfaceConnect(conn, driver, net,
-
net->data.direct.linkdev,
-
net->data.direct.mode,
qemuCmdFlags);
if (tapfd < 0)
goto error;
14 years, 7 months
[libvirt] [PATCH] Determine the root physical interface of a given interface
by Stefan Berger
In this patch I am adding functions that help to iteratively determine
the root physical interface of a given interface. An example would be
that a macvtap device is linked to eth0.100 which in turn is linked to
eth0. Given the name or interface index of the macvtap device that is
linked to eth0.100, eth0 is found by following the links to the end. I
am using now the netlink library to parse the returned netlink messages
and for that I am making additions to configure.ac and the rpm spec file
to check for the netlink and netlink-devel packages respectively. In the
configure.ac the requirement to have the netlink library is dependent on
having macvtap.
The setup of the upcoming VEPA patches requires knowledge over which
interface to run the setup protocol. In the above case the protocol
would need to run over interface eth0 and provide the knowledge of vlan
id 100 in the protocol (see previous patch).
Signed-off-by: Stefan Berger <stefanb(a)us.ibm.com>
---
configure.ac | 24 ++++++
libvirt.spec.in | 14 ++++
src/Makefile.am | 2
src/util/macvtap.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 224 insertions(+), 1 deletion(-)
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -41,6 +41,9 @@
# include <linux/rtnetlink.h>
# include <linux/if_tun.h>
+# include <netlink/attr.h>
+# include <netlink/msg.h>
+
# include "util.h"
# include "memory.h"
# include "macvtap.h"
@@ -421,6 +424,187 @@ buffer_too_small:
}
+static struct nla_policy ifla_policy[ IFLA_MAX + 1] =
+{
+ [IFLA_IFNAME ] = {.type = NLA_STRING },
+ [IFLA_LINK] = {.type = NLA_U32 },
+};
+
+
+static int
+link_dump(int ifindex, const char *ifname, struct nlattr **tb,
+ char **recvbuf)
+{
+ int rc = 0;
+ char nlmsgbuf[256];
+ struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+ struct nlmsgerr *err;
+ char rtattbuf[64];
+ struct rtattr *rta;
+ struct ifinfomsg i = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = ifindex
+ };
+ int recvbuflen;
+
+ *recvbuf = NULL;
+
+ memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
+
+ nlInit(nlm, NLM_F_REQUEST, RTM_GETLINK);
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), &i, sizeof(i)))
+ goto buffer_too_small;
+
+ if (ifindex < 0 && ifname != NULL) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_IFNAME,
+ ifname, strlen(ifname)+1);
+ if (!rta)
+ goto buffer_too_small;
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), rtattbuf, rta->rta_len))
+ goto buffer_too_small;
+ }
+
+ if (nlComm(nlm, recvbuf, &recvbuflen) < 0)
+ return -1;
+
+ if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
+ goto malformed_resp;
+
+ resp = (struct nlmsghdr *)*recvbuf;
+
+ switch (resp->nlmsg_type) {
+ case NLMSG_ERROR:
+ err = (struct nlmsgerr *)NLMSG_DATA(resp);
+ if (resp->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
+ goto malformed_resp;
+
+ switch (-err->error) {
+ case 0:
+ break;
+
+ default:
+ virReportSystemError(-err->error,
+ _("error dumping %d interface"),
+ ifindex);
+ rc = -1;
+ }
+ break;
+
+ case GENL_ID_CTRL:
+ case NLMSG_DONE:
+ if (nlmsg_parse(resp, sizeof(struct ifinfomsg),
+ tb, IFLA_MAX, ifla_policy)) {
+ goto malformed_resp;
+ }
+ break;
+
+ default:
+ goto malformed_resp;
+ }
+
+ if (rc != 0)
+ VIR_FREE(*recvbuf);
+
+ return rc;
+
+malformed_resp:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed netlink response message"));
+ VIR_FREE(*recvbuf);
+ return -1;
+
+buffer_too_small:
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("internal buffer is too small"));
+ return -1;
+}
+
+
+/* TODO: move this into interface.c after moving netlink functions into
+ * utils dir
+ */
+/**
+ * ifaceGetNthParent
+ *
+ * @ifindex : the index of the interface or -1 if ifname is given
+ * @ifname : the name of the interface; ignored if ifindex is valid
+ * @nthParent : the nth parent interface to get
+ * @rootifname : pointer to buffer of size IFNAMSIZ
+ * @nth : the nth parent that is actually returned; if for example eth0.100
+ * was given and the 100th parent is to be returned, then eth0 will
+ * most likely be returned with nth set to 1 since the chain does
+ * not have more interfaces
+ *
+ * Get the nth parent interface of the given interface. 0 is the interface
+ * itself.
+ *
+ * Return 0 on success, != 0 otherwise
+ */
+static int
+ifaceGetNthParent(int ifindex, const char *ifname, unsigned int nthParent,
+ char *rootifname, unsigned int *nth)
+{
+ int rc;
+ struct nlattr *tb[IFLA_MAX + 1];
+ char *recvbuf = NULL;
+ bool end = false;
+ unsigned int i = 0;
+
+ while (!end && i <= nthParent) {
+ rc = link_dump(ifindex, ifname, tb, &recvbuf);
+ if (rc)
+ break;
+
+ if (tb[IFLA_IFNAME]) {
+ if (!virStrcpy(rootifname, (char*)RTA_DATA(tb[IFLA_IFNAME]),
+ IFNAMSIZ)) {
+ macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("buffer for root interface name is too small"));
+ VIR_FREE(recvbuf);
+ return 1;
+ }
+ }
+
+ if (tb[IFLA_LINK]) {
+ ifindex = *(int *)RTA_DATA(tb[IFLA_LINK]);
+ ifname = NULL;
+ } else
+ end = true;
+
+ VIR_FREE(recvbuf);
+
+ i++;
+ }
+
+ if (nth)
+ *nth = i-1;
+
+ return rc;
+}
+
+
+/**
+ * ifaceGetRootIface
+ *
+ * @ifindex : the index of the interface or -1 if ifname is given
+ * @ifname : the name of the interface; ignored if ifindex is valid
+ * @rootifname : pointer to buffer of size IFNAMSIZ
+ *
+ * Get the root interface of a given interface, i.e., if macvtap
+ * is linked to eth0.100, it will return eth0.
+ *
+ * Return 0 on success, != 0 otherwise
+ */
+static int
+ifaceGetRootIface(int ifindex, const char *ifname,
+ char *rootifname)
+{
+ return ifaceGetNthParent(ifindex, ifname, ~0, rootifname, NULL);
+}
+
+
/* Open the macvtap's tap device.
* @ifname: Name of the macvtap interface
* @retries : Number of retries in case udev for example may need to be
Index: libvirt-acl/src/Makefile.am
===================================================================
--- libvirt-acl.orig/src/Makefile.am
+++ libvirt-acl/src/Makefile.am
@@ -932,7 +932,7 @@ libvirt_la_LDFLAGS = $(VERSION_SCRIPT_FL
-version-info $(LIBVIRT_VERSION_INFO) \
$(COVERAGE_CFLAGS:-f%=-Wc,-f%) \
$(LIBXML_LIBS) \
- $(LIBPCAP_LIBS) \
+ $(LIBPCAP_LIBS) $(LIBNL_LIBS) \
$(DRIVER_MODULE_LIBS) \
$(CYGWIN_EXTRA_LDFLAGS) $(MINGW_EXTRA_LDFLAGS)
libvirt_la_CFLAGS = $(COVERAGE_CFLAGS) -DIN_LIBVIRT
@@ -985,7 +985,7 @@ libvirt_lxc_SOURCES = \
$(NWFILTER_PARAM_CONF_SOURCES)
libvirt_lxc_LDFLAGS = $(WARN_CFLAGS) $(COVERAGE_LDCFLAGS) $(CAPNG_LIBS) $(YAJL_LIBS)
libvirt_lxc_LDADD = $(LIBXML_LIBS) $(NUMACTL_LIBS) $(LIB_PTHREAD) \
- ../gnulib/lib/libgnu.la
+ $(LIBNL_LIBS) ../gnulib/lib/libgnu.la
libvirt_lxc_CFLAGS = \
$(LIBPARTED_CFLAGS) \
$(NUMACTL_CFLAGS) \
Index: libvirt-acl/configure.ac
===================================================================
--- libvirt-acl.orig/configure.ac
+++ libvirt-acl/configure.ac
@@ -42,6 +42,7 @@ HAL_REQUIRED=0.5.0
DEVMAPPER_REQUIRED=1.0.0
LIBCURL_REQUIRED="7.18.0"
LIBPCAP_REQUIRED="1.0.0"
+LIBNL_REQUIRED="1.1"
dnl Checks for C compiler.
AC_PROG_CC
@@ -2005,6 +2006,24 @@ fi
AM_CONDITIONAL([WITH_MACVTAP], [test "$with_macvtap" = "yes"])
+dnl netlink library
+
+LIBNL_CFLAGS=""
+LIBNL_LIBS=""
+
+if test "$with_macvtap" = "yes"; then
+ PKG_CHECK_MODULES(LIBNL, libnl-1 >= $LIBNL_REQUIRED, [
+ ], [
+ AC_MSG_ERROR([libnl >= $LIBNL_REQUIRED is required for macvtap support])
+ ])
+fi
+
+AC_SUBST([LIBNL_CFLAGS])
+AC_SUBST([LIBNL_LIBS])
+
+
+
+
# Only COPYING.LIB is under version control, yet COPYING
# is included as part of the distribution tarball.
# Copy one to the other, but only if this is a srcdir-build.
@@ -2183,6 +2202,11 @@ AC_MSG_NOTICE([ pcap: $LIBPCAP_CFLAGS
else
AC_MSG_NOTICE([ pcap: no])
fi
+if test "$with_macvtap" = "yes" ; then
+AC_MSG_NOTICE([ nl: $LIBNL_CFLAGS $LIBNL_LIBS])
+else
+AC_MSG_NOTICE([ nl: no])
+fi
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Test suite])
AC_MSG_NOTICE([])
Index: libvirt-acl/libvirt.spec.in
===================================================================
--- libvirt-acl.orig/libvirt.spec.in
+++ libvirt-acl/libvirt.spec.in
@@ -63,6 +63,7 @@
%define with_yajl 0%{!?_without_yajl:0}
%define with_nwfilter 0%{!?_without_nwfilter:0}
%define with_libpcap 0%{!?_without_libpcap:0}
+%define with_macvtap 0%{!?_without_macvtap:0}
# Non-server/HV driver defaults which are always enabled
%define with_python 0%{!?_without_python:1}
@@ -153,6 +154,11 @@
%if %{with_qemu}
%define with_nwfilter 0%{!?_without_nwfilter:%{server_drivers}}
%define with_libpcap 0%{!?_without_libpcap:%{server_drivers}}
+%define with_macvtap 0%{!?_without_macvtap:%{server_drivers}}
+%endif
+
+%if %{with_macvtap}
+%define with_libnl 1
%endif
# Force QEMU to run as non-root
@@ -282,6 +288,9 @@ BuildRequires: yajl-devel
%if %{with_libpcap}
BuildRequires: libpcap-devel
%endif
+%if %{with_libnl}
+BuildRequires: libnl-devel
+%endif
%if %{with_avahi}
BuildRequires: avahi-devel
%endif
@@ -531,6 +540,10 @@ of recent versions of Linux (and other O
%define _without_libpcap --without-libpcap
%endif
+%if ! %{with_macvtap}
+%define _without_macvtap --without-macvtap
+%endif
+
%configure %{?_without_xen} \
%{?_without_qemu} \
%{?_without_openvz} \
@@ -560,6 +573,7 @@ of recent versions of Linux (and other O
%{?_without_udev} \
%{?_without_yajl} \
%{?_without_libpcap} \
+ %{?_without_macvtap} \
--with-qemu-user=%{qemu_user} \
--with-qemu-group=%{qemu_group} \
--with-init-script=redhat \
14 years, 7 months
[libvirt] [PATCH 0/2] build: update gnulib
by Eric Blake
The latest gnulib finds a couple more syntax-check cleanups,
but it also required some work to avoid requiring gettext 0.18
(since using software just released yesterday won't fly for
supporting RHEL5).
[PATCH 1/2] build: allow older gettext
[PATCH 2/2] build: update gnulib
.gnulib | 2 +-
bootstrap.conf | 2 +-
src/esx/esx_util.c | 6 ------
src/remote/remote_driver.c | 5 -----
tools/virsh.c | 7 +------
5 files changed, 3 insertions(+), 19 deletions(-)
14 years, 7 months
[libvirt] [PATCH] tests: correct PATH in new test, for when running manually
by Jim Meyering
I'd prepended a *file* to PATH, not the containing directory.
The bug would have shown up only when running this test manually.
>From 9339dec535beeeb18c96380f0163d3aeb604a0dc Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering(a)redhat.com>
Date: Tue, 11 May 2010 17:43:16 +0200
Subject: [PATCH] tests: correct PATH in new test, for when running manually
* tests/virsh-schedinfo: This test sets PATH internally, just in
case you're running it manually. Normally, the PATH setting from
tests/Makefile.am's TESTS_ENVIRONMENT is sufficient. Prepend the
correct directory, and take advantage of the PATH setting in one
more case.
---
tests/virsh-schedinfo | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/virsh-schedinfo b/tests/virsh-schedinfo
index b276a2e..a2ec193 100755
--- a/tests/virsh-schedinfo
+++ b/tests/virsh-schedinfo
@@ -20,17 +20,17 @@
: ${abs_top_srcdir=$(pwd)/..}
: ${abs_top_builddir=$(pwd)/..}
-# If $abs_top_builddir/tools/virsh is not early in $PATH, put it there,
+# If $abs_top_builddir/tools is not early in $PATH, put it there,
# so that we can safely invoke "virsh" simply with its name.
case $PATH in
- $abs_top_builddir/tools/src:$abs_top_builddir/tools/virsh:*) ;;
- $abs_top_builddir/tools/virsh:*) ;;
- *) PATH=$abs_top_builddir/tools/virsh:$PATH; export PATH ;;
+ $abs_top_builddir/tools/src:$abs_top_builddir/tools:*) ;;
+ $abs_top_builddir/tools:*) ;;
+ *) PATH=$abs_top_builddir/tools:$PATH; export PATH ;;
esac
if test "$VERBOSE" = yes; then
set -x
- $abs_top_builddir/tools/virsh --version
+ virsh --version
fi
. "$srcdir/test-lib.sh"
--
1.7.1.189.g07419
14 years, 7 months