[libvirt] [PATCH V3 1/3] Improve netlink to support all protocol.

Daniel Veillard veillard at redhat.com
Wed Aug 22 10:29:18 UTC 2012


On Wed, Aug 22, 2012 at 12:10:23PM +0800, Tang Chen wrote:
> This patch improve all the API in virnetlink.c to support
> all kinds of netlink protocols, and make all netlink sockets
> be able to join in groups.
> 
> Signed-off-by: Tang Chen <tangchen at cn.fujitsu.com>
> ---
>  daemon/libvirtd.c                |    6 +-
>  src/util/virnetdev.c             |    6 +-
>  src/util/virnetdevmacvlan.c      |   12 +--
>  src/util/virnetdevvportprofile.c |    7 +-
>  src/util/virnetlink.c            |  170 ++++++++++++++++++++++++++++----------
>  src/util/virnetlink.h            |   17 ++--
>  6 files changed, 156 insertions(+), 62 deletions(-)
> 
> diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
> index f0b0a3c..e2e4fbd 100644
> --- a/daemon/libvirtd.c
> +++ b/daemon/libvirtd.c
> @@ -1310,8 +1310,8 @@ int main(int argc, char **argv) {
>          goto cleanup;
>      }
>  
> -    /* Register the netlink event service */
> -    if (virNetlinkEventServiceStart() < 0) {
> +    /* Register the netlink event service for NETLINK_ROUTE */
> +    if (virNetlinkEventServiceStart(NETLINK_ROUTE, 0) < 0) {
>          ret = VIR_DAEMON_ERR_NETWORK;
>          goto cleanup;
>      }
> @@ -1325,7 +1325,7 @@ int main(int argc, char **argv) {
>                  0, "shutdown", NULL, NULL);
>  
>  cleanup:
> -    virNetlinkEventServiceStop();
> +    virNetlinkEventServiceStop(NETLINK_ROUTE);
>      virObjectUnref(remoteProgram);
>      virObjectUnref(qemuProgram);
>      virNetServerClose(srv);
> diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
> index f9eba1a..d97820e 100644
> --- a/src/util/virnetdev.c
> +++ b/src/util/virnetdev.c
> @@ -1277,7 +1277,8 @@ virNetDevLinkDump(const char *ifname, int ifindex,
>              goto buffer_too_small;
>      }
>  
> -    if (virNetlinkCommand(nl_msg, recvbuf, &recvbuflen, src_pid, dst_pid) < 0)
> +    if (virNetlinkCommand(nl_msg, recvbuf, &recvbuflen,
> +                          src_pid, dst_pid, NETLINK_ROUTE, 0) < 0)
>          goto cleanup;
>  
>      if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL)
> @@ -1405,7 +1406,8 @@ virNetDevSetVfConfig(const char *ifname, int ifindex, int vf,
>          }
>      }
>  
> -    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, pid) < 0)
> +    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, pid,
> +                          NETLINK_ROUTE, 0) < 0)
>          goto cleanup;
>  
>      if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
> diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
> index cfad2de..74c56e0 100644
> --- a/src/util/virnetdevmacvlan.c
> +++ b/src/util/virnetdevmacvlan.c
> @@ -149,7 +149,8 @@ virNetDevMacVLanCreate(const char *ifname,
>  
>      nla_nest_end(nl_msg, linkinfo);
>  
> -    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0) < 0) {
> +    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0,
> +                          NETLINK_ROUTE, 0) < 0) {
>          goto cleanup;
>      }
>  
> @@ -237,7 +238,8 @@ int virNetDevMacVLanDelete(const char *ifname)
>      if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
>          goto buffer_too_small;
>  
> -    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0) < 0) {
> +    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, 0, 0,
> +                          NETLINK_ROUTE, 0) < 0) {
>          goto cleanup;
>      }
>  
> @@ -757,7 +759,7 @@ virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
>  {
>      virNetlinkCallbackDataPtr calld = NULL;
>  
> -    if (virtPortProfile && virNetlinkEventServiceIsRunning()) {
> +    if (virtPortProfile && virNetlinkEventServiceIsRunning(NETLINK_ROUTE)) {
>          if (VIR_ALLOC(calld) < 0)
>              goto memory_error;
>          if ((calld->cr_ifname = strdup(ifname)) == NULL)
> @@ -774,7 +776,7 @@ virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
>  
>          if (virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback,
>                                       virNetDevMacVLanVPortProfileDestroyCallback,
> -                                     calld, macaddress) < 0)
> +                                     calld, macaddress, NETLINK_ROUTE) < 0)
>              goto error;
>      }
>  
> @@ -1000,7 +1002,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
>              ret = -1;
>      }
>  
> -    virNetlinkEventRemoveClient(0, macaddr);
> +    virNetlinkEventRemoveClient(0, macaddr, NETLINK_ROUTE);
>  
>      return ret;
>  }
> diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c
> index f3f53c9..5213378 100644
> --- a/src/util/virnetdevvportprofile.c
> +++ b/src/util/virnetdevvportprofile.c
> @@ -705,13 +705,14 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
>      }
>  
>      if (!nltarget_kernel) {
> -        if ((src_pid = virNetlinkEventServiceLocalPid()) < 0)
> +        if ((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0)
>              goto cleanup;
>          if ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0)
>              goto cleanup;
>      }
>  
> -    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen, src_pid, dst_pid) < 0)
> +    if (virNetlinkCommand(nl_msg, &recvbuf, &recvbuflen,
> +                          src_pid, dst_pid, NETLINK_ROUTE, 0) < 0)
>          goto cleanup;
>  
>      if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
> @@ -868,7 +869,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex,
>          return 0;
>  
>      if (!nltarget_kernel &&
> -        (((src_pid = virNetlinkEventServiceLocalPid()) < 0) ||
> +        (((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0) ||
>           ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0))) {
>          rc = -1;
>          goto cleanup;
> diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
> index 4a31b1c..64bd47d 100644
> --- a/src/util/virnetlink.c
> +++ b/src/util/virnetlink.c
> @@ -33,6 +33,7 @@
>  #include <errno.h>
>  #include <unistd.h>
>  #include <sys/types.h>
> +#include <sys/socket.h>
>  
>  #include "virnetlink.h"
>  #include "logging.h"
> @@ -41,6 +42,10 @@
>  #include "virmacaddr.h"
>  #include "virterror_internal.h"
>  
> +#ifndef SOL_NETLINK
> +#define SOL_NETLINK 270
> +#endif
> +

  This needed some indetation otherwise "make syntax-check" would
  complain. I wonder if MAX_LINKS shouldn't be checked too

#ifdef MAX_LINKS
# define MAX_LINKS 32
#endif

>  #define VIR_FROM_THIS VIR_FROM_NET
>  
>  #define NETLINK_ACK_TIMEOUT_S  2
> @@ -93,7 +98,9 @@ static int nextWatch = 1;
>   records in this multiple */
>  # define NETLINK_EVENT_ALLOC_EXTENT 10
>  
> -static virNetlinkEventSrvPrivatePtr server = NULL;
> +/* Linux kernel supports up to MAX_LINKS (32 at the time) individual
> + * netlink protocols. */
> +static virNetlinkEventSrvPrivatePtr server[MAX_LINKS] = {NULL};
>  static virNetlinkHandle *placeholder_nlhandle = NULL;
>  
>  /* Function definitions */
> @@ -157,7 +164,10 @@ virNetlinkShutdown(void)
>   * @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
> + * @src_pid: the pid of the process to send a message
> + * @dst_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
> + * @protocol: netlink protocol
> + * @groups: the group identifier
>   *
>   * Send the given message to the netlink layer and receive response.
>   * Returns 0 on success, -1 on error. In case of error, no response
> @@ -165,7 +175,8 @@ virNetlinkShutdown(void)
>   */
>  int virNetlinkCommand(struct nl_msg *nl_msg,
>                        unsigned char **respbuf, unsigned int *respbuflen,
> -                      uint32_t src_pid, uint32_t dst_pid)
> +                      uint32_t src_pid, uint32_t dst_pid,
> +                      unsigned int protocol, unsigned int groups)
>  {
>      int rc = 0;
>      struct sockaddr_nl nladdr = {
> @@ -181,17 +192,39 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
>      int fd;
>      int n;
>      struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
> -    virNetlinkHandle *nlhandle = virNetlinkAlloc();
> +    virNetlinkHandle *nlhandle = NULL;
> +    
> +    if (protocol >= MAX_LINKS) {
> +        virReportSystemError(EINVAL,
> +                             _("invalid protocol argument: %d"), protocol);
> +        return -EINVAL;
> +    }
>  
> +    nlhandle = virNetlinkAlloc();
>      if (!nlhandle) {
>          virReportSystemError(errno,
>                               "%s", _("cannot allocate nlhandle for netlink"));
>          return -1;
>      }
>  
> -    if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
> +    if (nl_connect(nlhandle, protocol) < 0) {
> +        virReportSystemError(errno,
> +                             _("cannot connect to netlink socket with protocol %d"), protocol);
> +        rc = -1;
> +        goto error;
> +    }
> +
> +    fd = nl_socket_get_fd(nlhandle);
> +    if (fd < 0) {
>          virReportSystemError(errno,
> -                             "%s", _("cannot connect to netlink socket"));
> +                             "%s", _("cannot get netlink socket fd"));
> +        rc = -1;
> +        goto error;
> +    }
> +
> +    if (groups && nl_socket_add_membership(nlhandle, groups) < 0) {
> +        virReportSystemError(errno,
> +                             "%s", _("cannot add netlink membership"));
>          rc = -1;
>          goto error;
>      }
> @@ -208,8 +241,6 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
>          goto error;
>      }
>  
> -    fd = nl_socket_get_fd(nlhandle);
> -
>      FD_ZERO(&readfds);
>      FD_SET(fd, &readfds);
>  
> @@ -258,6 +289,7 @@ virNetlinkEventServerUnlock(virNetlinkEventSrvPrivatePtr driver)
>   * virNetlinkEventRemoveClientPrimitive:
>   *
>   * @i: index of the client to remove from the table
> + * @protocol: netlink protocol
>   *
>   * This static function does the low level removal of a client from
>   * the table once its index is known, including calling the remove
> @@ -267,17 +299,21 @@ virNetlinkEventServerUnlock(virNetlinkEventSrvPrivatePtr driver)
>   *
>   * assumes success, returns nothing.
>   */
> -static void
> -virNetlinkEventRemoveClientPrimitive(size_t i)
> +static int
> +virNetlinkEventRemoveClientPrimitive(size_t i, unsigned int protocol)
>  {
> -    virNetlinkEventRemoveCallback removeCB = server->handles[i].removeCB;
> +    if (protocol >= MAX_LINKS)
> +        return -EINVAL;
> +
> +    virNetlinkEventRemoveCallback removeCB = server[protocol]->handles[i].removeCB;
>  
>      if (removeCB) {
> -        (removeCB)(server->handles[i].watch,
> -                   &server->handles[i].macaddr,
> -                   server->handles[i].opaque);
> +        (removeCB)(server[protocol]->handles[i].watch,
> +                   &server[protocol]->handles[i].macaddr,
> +                   server[protocol]->handles[i].opaque);
>      }
> -    server->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
> +    server[protocol]->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
> +    return 0;
>  }
>  
>  static void
> @@ -330,17 +366,22 @@ virNetlinkEventCallback(int watch,
>   * stop the monitor to receive netlink messages for libvirtd.
>   * This removes the netlink socket fd from the event handler.
>   *
> + * @protocol: netlink protocol
> + *
>   * Returns -1 if the monitor cannot be unregistered, 0 upon success
>   */
>  int
> -virNetlinkEventServiceStop(void)
> +virNetlinkEventServiceStop(unsigned int protocol)
>  {
> -    virNetlinkEventSrvPrivatePtr srv = server;
> +    if (protocol >= MAX_LINKS)
> +        return -EINVAL;
> +
> +    virNetlinkEventSrvPrivatePtr srv = server[protocol];
>      int i;
>  
>      VIR_INFO("stopping netlink event service");
>  
> -    if (!server)
> +    if (!server[protocol])
>          return 0;
>  
>      virNetlinkEventServerLock(srv);
> @@ -351,10 +392,10 @@ virNetlinkEventServiceStop(void)
>      /* free any remaining clients on the list */
>      for (i = 0; i < srv->handlesCount; i++) {
>          if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
> -            virNetlinkEventRemoveClientPrimitive(i);
> +            virNetlinkEventRemoveClientPrimitive(i, protocol);
>      }
>  
> -    server = 0;
> +    server[protocol] = NULL;
>      virNetlinkEventServerUnlock(srv);
>  
>      virMutexDestroy(&srv->lock);
> @@ -367,29 +408,42 @@ virNetlinkEventServiceStop(void)
>   *
>   * Returns if the netlink event service is running.
>   *
> + * @protocol: netlink protocol
> + *
>   * Returns 'true' if the service is running, 'false' if stopped.
>   */
>  bool
> -virNetlinkEventServiceIsRunning(void)
> +virNetlinkEventServiceIsRunning(unsigned int protocol)
>  {
> -    return server != NULL;
> +    if (protocol >= MAX_LINKS) {
> +        virReportSystemError(EINVAL,
> +                             _("invalid protocol argument: %d"), protocol);
> +        return false;
> +    }
> +
> +    return server[protocol] != NULL;
>  }
>  
>  /**
>   * virNetlinkEventServiceLocalPid:
>   *
> + * @protocol: netlink protocol
> + *
>   * Returns the nl_pid value that was used to bind() the netlink socket
>   * used by the netlink event service, or -1 on error (netlink
>   * guarantees that this value will always be > 0).
>   */
> -int virNetlinkEventServiceLocalPid(void)
> +int virNetlinkEventServiceLocalPid(unsigned int protocol)
>  {
> -    if (!(server && server->netlinknh)) {
> +    if (protocol >= MAX_LINKS)
> +        return -EINVAL;
> +
> +    if (!(server[protocol] && server[protocol]->netlinknh)) {
>          virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>                         _("netlink event service not running"));
>          return -1;
>      }
> -    return (int)nl_socket_get_local_port(server->netlinknh);
> +    return (int)nl_socket_get_local_port(server[protocol]->netlinknh);
>  }
>  
>  
> @@ -399,19 +453,27 @@ int virNetlinkEventServiceLocalPid(void)
>   * start a monitor to receive netlink messages for libvirtd.
>   * This registers a netlink socket with the event interface.
>   *
> + * @protocol: netlink protocol
> + * @groups: broadcast groups to join in
>   * Returns -1 if the monitor cannot be registered, 0 upon success
>   */
>  int
> -virNetlinkEventServiceStart(void)
> +virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
>  {
>      virNetlinkEventSrvPrivatePtr srv;
>      int fd;
>      int ret = -1;
>  
> -    if (server)
> +    if (protocol >= MAX_LINKS) {
> +        virReportSystemError(EINVAL,
> +                             _("invalid protocol argument: %d"), protocol);
> +        return -EINVAL;
> +    }
> +
> +    if (server[protocol])
>          return 0;
>  
> -    VIR_INFO("starting netlink event service");
> +    VIR_INFO("starting netlink event service with protocol %d", protocol);
>  
>      if (VIR_ALLOC(srv) < 0) {
>          virReportOOMError();
> @@ -434,20 +496,25 @@ virNetlinkEventServiceStart(void)
>          goto error_locked;
>      }
>  
> -    if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) {
> +    if (nl_connect(srv->netlinknh, protocol) < 0) {
>          virReportSystemError(errno,
> -                             "%s", _("cannot connect to netlink socket"));
> +                             _("cannot connect to netlink socket with protocol %d"), protocol);
>          goto error_server;
>      }
>  
>      fd = nl_socket_get_fd(srv->netlinknh);
> -
>      if (fd < 0) {
>          virReportSystemError(errno,
>                               "%s", _("cannot get netlink socket fd"));
>          goto error_server;
>      }
>  
> +    if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) {
> +        virReportSystemError(errno,
> +                             "%s", _("cannot add netlink membership"));
> +        goto error_server;
> +    }
> +
>      if (nl_socket_set_nonblocking(srv->netlinknh)) {
>          virReportSystemError(errno, "%s",
>                               _("cannot set netlink socket nonblocking"));
> @@ -467,7 +534,7 @@ virNetlinkEventServiceStart(void)
>      VIR_DEBUG("netlink event listener on fd: %i running", fd);
>  
>      ret = 0;
> -    server = srv;
> +    server[protocol] = srv;
>  
>  error_server:
>      if (ret < 0) {
> @@ -491,6 +558,7 @@ error_locked:
>   * @opaque: user data to pass to callback
>   * @macaddr: macaddr to store with the data. Used to identify callers.
>   *           May be null.
> + * @protocol: netlink protocol
>   *
>   * register a callback for handling of netlink messages. The
>   * registered function receives the entire netlink message and
> @@ -502,10 +570,16 @@ error_locked:
>  int
>  virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
>                           virNetlinkEventRemoveCallback removeCB,
> -                         void *opaque, const virMacAddrPtr macaddr)
> +                         void *opaque, const virMacAddrPtr macaddr,
> +                         unsigned int protocol)
>  {
>      int i, r, ret = -1;
> -    virNetlinkEventSrvPrivatePtr srv = server;
> +    virNetlinkEventSrvPrivatePtr srv = NULL;
> +    
> +    if (protocol >= MAX_LINKS)
> +        return -EINVAL;
> +
> +    srv = server[protocol];
>  
>      if (handleCB == NULL) {
>          virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> @@ -562,6 +636,7 @@ error:
>   *
>   * @watch: watch whose handle to remove
>   * @macaddr: macaddr whose handle to remove
> + * @protocol: netlink protocol
>   *
>   * Unregister a callback from a netlink monitor.
>   * The handler function referenced will no longer receive netlink messages.
> @@ -570,11 +645,17 @@ error:
>   * Returns -1 if the file handle was not registered, 0 upon success
>   */
>  int
> -virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr)
> +virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
> +                            unsigned int protocol)
>  {
>      int i;
>      int ret = -1;
> -    virNetlinkEventSrvPrivatePtr srv = server;
> +    virNetlinkEventSrvPrivatePtr srv = NULL;
> +
> +    if (protocol >= MAX_LINKS)
> +        return -EINVAL;
> +
> +    srv = server[protocol];
>  
>      VIR_DEBUG("removing client watch=%d, mac=%p.", watch, macaddr);
>  
> @@ -595,7 +676,7 @@ virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr)
>  
>              VIR_DEBUG("removed client: %d by %s.",
>                        srv->handles[i].watch, watch ? "index" : "mac");
> -            virNetlinkEventRemoveClientPrimitive(i);
> +            virNetlinkEventRemoveClientPrimitive(i, protocol);
>              ret = 0;
>              goto cleanup;
>          }
> @@ -631,7 +712,9 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
>                        unsigned char **respbuf ATTRIBUTE_UNUSED,
>                        unsigned int *respbuflen ATTRIBUTE_UNUSED,
>                        uint32_t src_pid ATTRIBUTE_UNUSED,
> -                      uint32_t dst_pid ATTRIBUTE_UNUSED)
> +                      uint32_t dst_pid ATTRIBUTE_UNUSED,
> +                      unsigned int protocol ATTRIBUTE_UNUSED,
> +                      unsigned int groups ATTRIBUTE_UNUSED)
>  {
>      virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
>      return -1;
> @@ -641,7 +724,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
>   * stopNetlinkEventServer: stop the monitor to receive netlink
>   * messages for libvirtd
>   */
> -int virNetlinkEventServiceStop(void)
> +int virNetlinkEventServiceStop(unsigned int protocol ATTRIBUTE_UNUSED)
>  {
>      VIR_DEBUG("%s", _(unsupported));
>      return 0;
> @@ -651,7 +734,8 @@ int virNetlinkEventServiceStop(void)
>   * startNetlinkEventServer: start a monitor to receive netlink
>   * messages for libvirtd
>   */
> -int virNetlinkEventServiceStart(void)
> +int virNetlinkEventServiceStart(unsigned int protocol ATTRIBUTE_UNUSED,
> +                                unsigned int groups ATTRIBUTE_UNUSED)
>  {
>      VIR_DEBUG("%s", _(unsupported));
>      return 0;
> @@ -661,13 +745,13 @@ int virNetlinkEventServiceStart(void)
>   * virNetlinkEventServiceIsRunning: returns if the netlink event
>   * service is running.
>   */
> -bool virNetlinkEventServiceIsRunning(void)
> +bool virNetlinkEventServiceIsRunning(unsigned int protocol ATTRIBUTE_UNUSED)
>  {
>      virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
>      return 0;
>  }
>  
> -int virNetlinkEventServiceLocalPid(void)
> +int virNetlinkEventServiceLocalPid(unsigned int protocol ATTRIBUTE_UNUSED)
>  {
>      virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
>      return -1;
> @@ -681,6 +765,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UN
>                               virNetlinkEventRemoveCallback removeCB ATTRIBUTE_UNUSED,
>                               void *opaque ATTRIBUTE_UNUSED,
>                               const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)
> +                             unsigned int protocol ATTRIBUTE_UNUSED)
>  {
>      virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
>      return -1;
> @@ -691,6 +776,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UN
>   */
>  int virNetlinkEventRemoveClient(int watch ATTRIBUTE_UNUSED,
>                                  const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)
> +                                unsigned int protocol ATTRIBUTE_UNUSED)
>  {
>      virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
>      return -1;
> diff --git a/src/util/virnetlink.h b/src/util/virnetlink.h
> index 5d8337d..2e18af4 100644
> --- a/src/util/virnetlink.h
> +++ b/src/util/virnetlink.h
> @@ -41,7 +41,8 @@ void virNetlinkShutdown(void);
>  
>  int virNetlinkCommand(struct nl_msg *nl_msg,
>                        unsigned char **respbuf, unsigned int *respbuflen,
> -                      uint32_t src_port, uint32_t dst_port);
> +                      uint32_t src_pid, uint32_t dst_pid,
> +                      unsigned int protocol, unsigned int groups);
>  
>  typedef void (*virNetlinkEventHandleCallback)(unsigned char *msg, int length, struct sockaddr_nl *peer, bool *handled, void *opaque);
>  
> @@ -50,33 +51,35 @@ typedef void (*virNetlinkEventRemoveCallback)(int watch, const virMacAddrPtr mac
>  /**
>   * stopNetlinkEventServer: stop the monitor to receive netlink messages for libvirtd
>   */
> -int virNetlinkEventServiceStop(void);
> +int virNetlinkEventServiceStop(unsigned int protocol);
>  
>  /**
>   * startNetlinkEventServer: start a monitor to receive netlink messages for libvirtd
>   */
> -int virNetlinkEventServiceStart(void);
> +int virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups);
>  
>  /**
>   * virNetlinkEventServiceIsRunning: returns if the netlink event service is running.
>   */
> -bool virNetlinkEventServiceIsRunning(void);
> +bool virNetlinkEventServiceIsRunning(unsigned int protocol);
>  
>  /**
>   * virNetlinkEventServiceLocalPid: returns nl_pid used to bind() netlink socket
>   */
> -int virNetlinkEventServiceLocalPid(void);
> +int virNetlinkEventServiceLocalPid(unsigned int protocol);
>  
>  /**
>   * virNetlinkEventAddClient: register a callback for handling of netlink messages
>   */
>  int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
>                               virNetlinkEventRemoveCallback removeCB,
> -                             void *opaque, const virMacAddrPtr macaddr);
> +                             void *opaque, const virMacAddrPtr macaddr,
> +                             unsigned int protocol);
>  
>  /**
>   * virNetlinkEventRemoveClient: unregister a callback from a netlink monitor
>   */
> -int virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr);
> +int virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
> +                                unsigned int protocol);
>  
>  #endif /* __VIR_NETLINK_H__ */

  Overall looks fine, though i had to apply the following patch for
  cleanup, ACK

Daniel

diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index 64bd47d..1ec9976 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -43,7 +43,7 @@
 #include "virterror_internal.h"
 
 #ifndef SOL_NETLINK
-#define SOL_NETLINK 270
+# define SOL_NETLINK 270
 #endif
 
 #define VIR_FROM_THIS VIR_FROM_NET
@@ -193,7 +193,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
     int n;
     struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
     virNetlinkHandle *nlhandle = NULL;
-    
+
     if (protocol >= MAX_LINKS) {
         virReportSystemError(EINVAL,
                              _("invalid protocol argument: %d"), protocol);
@@ -209,7 +209,8 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
 
     if (nl_connect(nlhandle, protocol) < 0) {
         virReportSystemError(errno,
-                             _("cannot connect to netlink socket with protocol %d"), protocol);
+                        _("cannot connect to netlink socket with protocol %d"),
+                             protocol);
         rc = -1;
         goto error;
     }
@@ -575,7 +576,7 @@ virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
 {
     int i, r, ret = -1;
     virNetlinkEventSrvPrivatePtr srv = NULL;
-    
+
     if (protocol >= MAX_LINKS)
         return -EINVAL;
 

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list