In a first cleanup step, make nlComm from macvtap.c commonly available
for other code to use. Since nlComm uses Linux-specific structures as
parameters it's prototype is only visible on Linux.
v2:
- making nlComm visible also on non-Linux platforms
Signed-off-by: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
---
src/Makefile.am | 1
src/libvirt_private.syms | 4 +
src/util/macvtap.c | 98 ------------------------------
src/util/netlink.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++
src/util/netlink.h | 18 +++++
5 files changed, 176 insertions(+), 97 deletions(-)
Index: libvirt-acl/src/Makefile.am
===================================================================
--- libvirt-acl.orig/src/Makefile.am
+++ libvirt-acl/src/Makefile.am
@@ -63,6 +63,7 @@ UTIL_SOURCES = \
util/logging.c util/logging.h \
util/macvtap.c util/macvtap.h \
util/memory.c util/memory.h \
+ util/netlink.c util/netlink.h \
util/pci.c util/pci.h \
util/processinfo.c util/processinfo.h \
util/hostusb.c util/hostusb.h \
Index: libvirt-acl/src/util/macvtap.c
===================================================================
--- libvirt-acl.orig/src/util/macvtap.c
+++ libvirt-acl/src/util/macvtap.c
@@ -39,12 +39,8 @@
# include <sys/ioctl.h>
# include <linux/if.h>
-# include <linux/netlink.h>
-# include <linux/rtnetlink.h>
# include <linux/if_tun.h>
-# include <netlink/msg.h>
-
/* Older kernels lacked this enum value. */
# if !HAVE_DECL_MACVLAN_MODE_PASSTHRU
# define MACVLAN_MODE_PASSTHRU 8
@@ -64,6 +60,7 @@
# include "virterror_internal.h"
# include "uuid.h"
# include "files.h"
+# include "netlink.h"
# define VIR_FROM_THIS VIR_FROM_NET
@@ -79,8 +76,6 @@
# define NLMSGBUF_SIZE 256
# define RATTBUF_SIZE 64
-# define NETLINK_ACK_TIMEOUT_S 2
-
# define STATUS_POLL_TIMEOUT_USEC (10 * MICROSEC_PER_SEC)
# define STATUS_POLL_INTERVL_USEC (MICROSEC_PER_SEC / 8)
@@ -96,97 +91,6 @@ enum virVirtualPortOp {
};
-/**
- * nlComm:
- * @nlmsg: pointer to netlink message
- * @respbuf: pointer to pointer where response buffer will be allocated
- * @respbuflen: pointer to integer holding the size of the response buffer
- * on return of the function.
- * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
- *
- * Send the given message to the netlink layer and receive response.
- * Returns 0 on success, -1 on error. In case of error, no response
- * buffer will be returned.
- */
-static
-int nlComm(struct nl_msg *nl_msg,
- unsigned char **respbuf, unsigned int *respbuflen,
- int nl_pid)
-{
- int rc = 0;
- struct sockaddr_nl nladdr = {
- .nl_family = AF_NETLINK,
- .nl_pid = nl_pid,
- .nl_groups = 0,
- };
- ssize_t nbytes;
- struct timeval tv = {
- .tv_sec = NETLINK_ACK_TIMEOUT_S,
- };
- fd_set readfds;
- int fd;
- int n;
- struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
- struct nl_handle *nlhandle = nl_handle_alloc();
-
- if (!nlhandle) {
- virReportSystemError(errno,
- "%s", _("cannot allocate nlhandle for
netlink"));
- return -1;
- }
-
- if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
- virReportSystemError(errno,
- "%s", _("cannot connect to netlink
socket"));
- rc = -1;
- goto err_exit;
- }
-
- nlmsg_set_dst(nl_msg, &nladdr);
-
- nlmsg->nlmsg_pid = getpid();
-
- nbytes = nl_send_auto_complete(nlhandle, nl_msg);
- if (nbytes < 0) {
- virReportSystemError(errno,
- "%s", _("cannot send to netlink
socket"));
- rc = -1;
- goto err_exit;
- }
-
- fd = nl_socket_get_fd(nlhandle);
-
- FD_ZERO(&readfds);
- FD_SET(fd, &readfds);
-
- n = select(fd + 1, &readfds, NULL, NULL, &tv);
- if (n <= 0) {
- if (n < 0)
- virReportSystemError(errno, "%s",
- _("error in select call"));
- if (n == 0)
- virReportSystemError(ETIMEDOUT, "%s",
- _("no valid netlink response was received"));
- rc = -1;
- goto err_exit;
- }
-
- *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
- if (*respbuflen <= 0) {
- virReportSystemError(errno,
- "%s", _("nl_recv failed"));
- rc = -1;
- }
-err_exit:
- if (rc == -1) {
- VIR_FREE(*respbuf);
- *respbuf = NULL;
- *respbuflen = 0;
- }
-
- nl_handle_destroy(nlhandle);
- return rc;
-}
# if WITH_MACVTAP
Index: libvirt-acl/src/util/netlink.c
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/netlink.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Authors:
+ * Stefan Berger <stefanb(a)us.ibm.com>
+ *
+ * Notes:
+ * netlink:
http://lovezutto.googlepages.com/netlink.pdf
+ * iproute2 package
+ *
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "netlink.h"
+#include "memory.h"
+#include "virterror_internal.h"
+
+#define VIR_FROM_THIS VIR_FROM_NET
+
+# define netlinkError(code, ...) \
+ virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \
+ __FUNCTION__, __LINE__, __VA_ARGS__)
+
+#define NETLINK_ACK_TIMEOUT_S 2
+
+/**
+ * nlComm:
+ * @nlmsg: pointer to netlink message
+ * @respbuf: pointer to pointer where response buffer will be allocated
+ * @respbuflen: pointer to integer holding the size of the response buffer
+ * on return of the function.
+ * @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
+ *
+ * Send the given message to the netlink layer and receive response.
+ * Returns 0 on success, -1 on error. In case of error, no response
+ * buffer will be returned.
+ */
+#if __linux__
+int nlComm(struct nl_msg *nl_msg,
+ unsigned char **respbuf, unsigned int *respbuflen,
+ int nl_pid)
+{
+ int rc = 0;
+ struct sockaddr_nl nladdr = {
+ .nl_family = AF_NETLINK,
+ .nl_pid = nl_pid,
+ .nl_groups = 0,
+ };
+ ssize_t nbytes;
+ struct timeval tv = {
+ .tv_sec = NETLINK_ACK_TIMEOUT_S,
+ };
+ fd_set readfds;
+ int fd;
+ int n;
+ struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
+ struct nl_handle *nlhandle = nl_handle_alloc();
+
+ if (!nlhandle) {
+ virReportSystemError(errno,
+ "%s", _("cannot allocate nlhandle for
netlink"));
+ return -1;
+ }
+
+ if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
+ virReportSystemError(errno,
+ "%s", _("cannot connect to netlink
socket"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ nlmsg_set_dst(nl_msg, &nladdr);
+
+ nlmsg->nlmsg_pid = getpid();
+
+ nbytes = nl_send_auto_complete(nlhandle, nl_msg);
+ if (nbytes < 0) {
+ virReportSystemError(errno,
+ "%s", _("cannot send to netlink
socket"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ fd = nl_socket_get_fd(nlhandle);
+
+ FD_ZERO(&readfds);
+ FD_SET(fd, &readfds);
+
+ n = select(fd + 1, &readfds, NULL, NULL, &tv);
+ if (n <= 0) {
+ if (n < 0)
+ virReportSystemError(errno, "%s",
+ _("error in select call"));
+ if (n == 0)
+ virReportSystemError(ETIMEDOUT, "%s",
+ _("no valid netlink response was received"));
+ rc = -1;
+ goto err_exit;
+ }
+
+ *respbuflen = nl_recv(nlhandle, &nladdr, respbuf, NULL);
+ if (*respbuflen <= 0) {
+ virReportSystemError(errno,
+ "%s", _("nl_recv failed"));
+ rc = -1;
+ }
+err_exit:
+ if (rc == -1) {
+ VIR_FREE(*respbuf);
+ *respbuf = NULL;
+ *respbuflen = 0;
+ }
+
+ nl_handle_destroy(nlhandle);
+ return rc;
+}
+
+#else
+
+int nlComm(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
+ unsigned char **respbuf ATTRIBUTE_UNUSED,
+ unsigned int *respbuflen ATTRIBUTE_UNUSED,
+ int nl_pid ATTRIBUTE_UNUSED)
+{
+ netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("nlComm is not supported on non-linux platforms"));
+ return -1;
+}
+
+
+#endif /* __linux__ */
+
Index: libvirt-acl/src/util/netlink.h
===================================================================
--- /dev/null
+++ libvirt-acl/src/util/netlink.h
@@ -0,0 +1,18 @@
+#ifndef __VIR_NETLINK_H__
+# define __VIR_NETLINK_H__
+
+# if __linux__
+
+# include <netlink/msg.h>
+
+# else
+
+struct nl_msg;
+
+#endif /* __linux__ */
+
+int nlComm(struct nl_msg *nl_msg,
+ unsigned char **respbuf, unsigned int *respbuflen,
+ int nl_pid);
+
+#endif /* __VIR_NETLINK_H__ */
Index: libvirt-acl/src/libvirt_private.syms
===================================================================
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -668,6 +668,10 @@ virResizeN;
virShrinkN;
+#netlink.h
+nlComm;
+
+
# network.h
virSocketAddrBroadcast;
virSocketAddrBroadcastByPrefix;