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@xxxxxxxxxxxxxxxxxx> --- 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@xxxxxxxxxx> + * + * 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; -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list