]> xenbits.xensource.com Git - libvirt.git/commitdiff
cleanup: make nlComm commonly available
authorStefan Berger <stefanb@us.ibm.com>
Wed, 22 Jun 2011 18:17:36 +0000 (14:17 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Wed, 22 Jun 2011 18:17:36 +0000 (14:17 -0400)
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.

po/POTFILES.in
src/Makefile.am
src/libvirt_private.syms
src/util/macvtap.c
src/util/netlink.c [new file with mode: 0644]
src/util/netlink.h [new file with mode: 0644]

index 81de425a6f603b0a4ac912504df3e08586cb8772..4ea1b782f820ee38003254a5af2bc83dbf546385 100644 (file)
@@ -101,6 +101,7 @@ src/util/interface.c
 src/util/iptables.c
 src/util/json.c
 src/util/macvtap.c
+src/util/netlink.c
 src/util/network.c
 src/util/pci.c
 src/util/processinfo.c
index 4f9bfc9a97b86bf7bd27811240794aea45c5b593..b292f9f284fafabc3d13dba0961f2d5fbe36880d 100644 (file)
@@ -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 6f253ab30fd8b4f611b341bb13326efe164d49b8..a0fd92215c6462e68d9fe718d778b1cbbafe59e6 100644 (file)
@@ -670,6 +670,10 @@ virResizeN;
 virShrinkN;
 
 
+#netlink.h
+nlComm;
+
+
 # network.h
 virSocketAddrBroadcast;
 virSocketAddrBroadcastByPrefix;
index ad1e3f3e4ed8547923bc3c608337d5669ace43c0..d651f7b1ac8f1aa1ab535c05f7458a291d19a1c8 100644 (file)
 # 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
@@ -69,6 +65,7 @@ VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST,
 # include "virterror_internal.h"
 # include "uuid.h"
 # include "files.h"
+# include "netlink.h"
 
 # define VIR_FROM_THIS VIR_FROM_NET
 
@@ -84,8 +81,6 @@ VIR_ENUM_IMPL(virMacvtapMode, VIR_MACVTAP_MODE_LAST,
 # 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)
 
@@ -101,97 +96,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
diff --git a/src/util/netlink.c b/src/util/netlink.c
new file mode 100644 (file)
index 0000000..411fa5b
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * 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@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__ */
diff --git a/src/util/netlink.h b/src/util/netlink.h
new file mode 100644 (file)
index 0000000..dc634aa
--- /dev/null
@@ -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__ */