1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-01-25 10:03:49 +03:00

Improve netlink to support all protocol.

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@cn.fujitsu.com>
This commit is contained in:
Tang Chen 2012-08-22 12:10:23 +08:00 committed by Daniel Veillard
parent 225f280744
commit d575679401
6 changed files with 157 additions and 62 deletions

View File

@ -1312,8 +1312,8 @@ int main(int argc, char **argv) {
goto cleanup; goto cleanup;
} }
/* Register the netlink event service */ /* Register the netlink event service for NETLINK_ROUTE */
if (virNetlinkEventServiceStart() < 0) { if (virNetlinkEventServiceStart(NETLINK_ROUTE, 0) < 0) {
ret = VIR_DAEMON_ERR_NETWORK; ret = VIR_DAEMON_ERR_NETWORK;
goto cleanup; goto cleanup;
} }
@ -1327,7 +1327,7 @@ int main(int argc, char **argv) {
0, "shutdown", NULL, NULL); 0, "shutdown", NULL, NULL);
cleanup: cleanup:
virNetlinkEventServiceStop(); virNetlinkEventServiceStop(NETLINK_ROUTE);
virObjectUnref(remoteProgram); virObjectUnref(remoteProgram);
virObjectUnref(qemuProgram); virObjectUnref(qemuProgram);
virNetServerClose(srv); virNetServerClose(srv);

View File

@ -1277,7 +1277,8 @@ virNetDevLinkDump(const char *ifname, int ifindex,
goto buffer_too_small; 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; goto cleanup;
if (recvbuflen < NLMSG_LENGTH(0) || *recvbuf == NULL) 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; goto cleanup;
if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)

View File

@ -149,7 +149,8 @@ virNetDevMacVLanCreate(const char *ifname,
nla_nest_end(nl_msg, linkinfo); 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; goto cleanup;
} }
@ -237,7 +238,8 @@ int virNetDevMacVLanDelete(const char *ifname)
if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0) if (nla_put(nl_msg, IFLA_IFNAME, strlen(ifname)+1, ifname) < 0)
goto buffer_too_small; 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; goto cleanup;
} }
@ -757,7 +759,7 @@ virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
{ {
virNetlinkCallbackDataPtr calld = NULL; virNetlinkCallbackDataPtr calld = NULL;
if (virtPortProfile && virNetlinkEventServiceIsRunning()) { if (virtPortProfile && virNetlinkEventServiceIsRunning(NETLINK_ROUTE)) {
if (VIR_ALLOC(calld) < 0) if (VIR_ALLOC(calld) < 0)
goto memory_error; goto memory_error;
if ((calld->cr_ifname = strdup(ifname)) == NULL) if ((calld->cr_ifname = strdup(ifname)) == NULL)
@ -774,7 +776,7 @@ virNetDevMacVLanVPortProfileRegisterCallback(const char *ifname,
if (virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback, if (virNetlinkEventAddClient(virNetDevMacVLanVPortProfileCallback,
virNetDevMacVLanVPortProfileDestroyCallback, virNetDevMacVLanVPortProfileDestroyCallback,
calld, macaddress) < 0) calld, macaddress, NETLINK_ROUTE) < 0)
goto error; goto error;
} }
@ -1000,7 +1002,7 @@ int virNetDevMacVLanDeleteWithVPortProfile(const char *ifname,
ret = -1; ret = -1;
} }
virNetlinkEventRemoveClient(0, macaddr); virNetlinkEventRemoveClient(0, macaddr, NETLINK_ROUTE);
return ret; return ret;
} }

View File

@ -705,13 +705,14 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int ifindex,
} }
if (!nltarget_kernel) { if (!nltarget_kernel) {
if ((src_pid = virNetlinkEventServiceLocalPid()) < 0) if ((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0)
goto cleanup; goto cleanup;
if ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0) if ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0)
goto cleanup; 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; goto cleanup;
if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL) if (recvbuflen < NLMSG_LENGTH(0) || recvbuf == NULL)
@ -868,7 +869,7 @@ virNetDevVPortProfileOpCommon(const char *ifname, int ifindex,
return 0; return 0;
if (!nltarget_kernel && if (!nltarget_kernel &&
(((src_pid = virNetlinkEventServiceLocalPid()) < 0) || (((src_pid = virNetlinkEventServiceLocalPid(NETLINK_ROUTE)) < 0) ||
((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0))) { ((dst_pid = virNetDevVPortProfileGetLldpadPid()) == 0))) {
rc = -1; rc = -1;
goto cleanup; goto cleanup;

View File

@ -33,6 +33,7 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h>
#include "virnetlink.h" #include "virnetlink.h"
#include "logging.h" #include "logging.h"
@ -41,6 +42,10 @@
#include "virmacaddr.h" #include "virmacaddr.h"
#include "virterror_internal.h" #include "virterror_internal.h"
#ifndef SOL_NETLINK
# define SOL_NETLINK 270
#endif
#define VIR_FROM_THIS VIR_FROM_NET #define VIR_FROM_THIS VIR_FROM_NET
#define NETLINK_ACK_TIMEOUT_S 2 #define NETLINK_ACK_TIMEOUT_S 2
@ -93,7 +98,9 @@ static int nextWatch = 1;
records in this multiple */ records in this multiple */
# define NETLINK_EVENT_ALLOC_EXTENT 10 # 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; static virNetlinkHandle *placeholder_nlhandle = NULL;
/* Function definitions */ /* Function definitions */
@ -157,7 +164,10 @@ virNetlinkShutdown(void)
* @respbuf: pointer to pointer where response buffer will be allocated * @respbuf: pointer to pointer where response buffer will be allocated
* @respbuflen: pointer to integer holding the size of the response buffer * @respbuflen: pointer to integer holding the size of the response buffer
* on return of the function. * 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. * Send the given message to the netlink layer and receive response.
* Returns 0 on success, -1 on error. In case of error, no 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, int virNetlinkCommand(struct nl_msg *nl_msg,
unsigned char **respbuf, unsigned int *respbuflen, 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; int rc = 0;
struct sockaddr_nl nladdr = { struct sockaddr_nl nladdr = {
@ -181,17 +192,40 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
int fd; int fd;
int n; int n;
struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg); 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) { if (!nlhandle) {
virReportSystemError(errno, virReportSystemError(errno,
"%s", _("cannot allocate nlhandle for netlink")); "%s", _("cannot allocate nlhandle for netlink"));
return -1; return -1;
} }
if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) { if (nl_connect(nlhandle, protocol) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
"%s", _("cannot connect to netlink socket")); _("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 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; rc = -1;
goto error; goto error;
} }
@ -208,8 +242,6 @@ int virNetlinkCommand(struct nl_msg *nl_msg,
goto error; goto error;
} }
fd = nl_socket_get_fd(nlhandle);
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(fd, &readfds); FD_SET(fd, &readfds);
@ -258,6 +290,7 @@ virNetlinkEventServerUnlock(virNetlinkEventSrvPrivatePtr driver)
* virNetlinkEventRemoveClientPrimitive: * virNetlinkEventRemoveClientPrimitive:
* *
* @i: index of the client to remove from the table * @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 * This static function does the low level removal of a client from
* the table once its index is known, including calling the remove * the table once its index is known, including calling the remove
@ -267,17 +300,21 @@ virNetlinkEventServerUnlock(virNetlinkEventSrvPrivatePtr driver)
* *
* assumes success, returns nothing. * assumes success, returns nothing.
*/ */
static void static int
virNetlinkEventRemoveClientPrimitive(size_t i) 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) { if (removeCB) {
(removeCB)(server->handles[i].watch, (removeCB)(server[protocol]->handles[i].watch,
&server->handles[i].macaddr, &server[protocol]->handles[i].macaddr,
server->handles[i].opaque); 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 static void
@ -330,17 +367,22 @@ virNetlinkEventCallback(int watch,
* stop the monitor to receive netlink messages for libvirtd. * stop the monitor to receive netlink messages for libvirtd.
* This removes the netlink socket fd from the event handler. * This removes the netlink socket fd from the event handler.
* *
* @protocol: netlink protocol
*
* Returns -1 if the monitor cannot be unregistered, 0 upon success * Returns -1 if the monitor cannot be unregistered, 0 upon success
*/ */
int int
virNetlinkEventServiceStop(void) virNetlinkEventServiceStop(unsigned int protocol)
{ {
virNetlinkEventSrvPrivatePtr srv = server; if (protocol >= MAX_LINKS)
return -EINVAL;
virNetlinkEventSrvPrivatePtr srv = server[protocol];
int i; int i;
VIR_INFO("stopping netlink event service"); VIR_INFO("stopping netlink event service");
if (!server) if (!server[protocol])
return 0; return 0;
virNetlinkEventServerLock(srv); virNetlinkEventServerLock(srv);
@ -351,10 +393,10 @@ virNetlinkEventServiceStop(void)
/* free any remaining clients on the list */ /* free any remaining clients on the list */
for (i = 0; i < srv->handlesCount; i++) { for (i = 0; i < srv->handlesCount; i++) {
if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID) if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
virNetlinkEventRemoveClientPrimitive(i); virNetlinkEventRemoveClientPrimitive(i, protocol);
} }
server = 0; server[protocol] = NULL;
virNetlinkEventServerUnlock(srv); virNetlinkEventServerUnlock(srv);
virMutexDestroy(&srv->lock); virMutexDestroy(&srv->lock);
@ -367,29 +409,42 @@ virNetlinkEventServiceStop(void)
* *
* Returns if the netlink event service is running. * Returns if the netlink event service is running.
* *
* @protocol: netlink protocol
*
* Returns 'true' if the service is running, 'false' if stopped. * Returns 'true' if the service is running, 'false' if stopped.
*/ */
bool 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: * virNetlinkEventServiceLocalPid:
* *
* @protocol: netlink protocol
*
* Returns the nl_pid value that was used to bind() the netlink socket * Returns the nl_pid value that was used to bind() the netlink socket
* used by the netlink event service, or -1 on error (netlink * used by the netlink event service, or -1 on error (netlink
* guarantees that this value will always be > 0). * 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", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("netlink event service not running")); _("netlink event service not running"));
return -1; return -1;
} }
return (int)nl_socket_get_local_port(server->netlinknh); return (int)nl_socket_get_local_port(server[protocol]->netlinknh);
} }
@ -399,19 +454,27 @@ int virNetlinkEventServiceLocalPid(void)
* start a monitor to receive netlink messages for libvirtd. * start a monitor to receive netlink messages for libvirtd.
* This registers a netlink socket with the event interface. * 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 * Returns -1 if the monitor cannot be registered, 0 upon success
*/ */
int int
virNetlinkEventServiceStart(void) virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
{ {
virNetlinkEventSrvPrivatePtr srv; virNetlinkEventSrvPrivatePtr srv;
int fd; int fd;
int ret = -1; int ret = -1;
if (server) if (protocol >= MAX_LINKS) {
virReportSystemError(EINVAL,
_("invalid protocol argument: %d"), protocol);
return -EINVAL;
}
if (server[protocol])
return 0; return 0;
VIR_INFO("starting netlink event service"); VIR_INFO("starting netlink event service with protocol %d", protocol);
if (VIR_ALLOC(srv) < 0) { if (VIR_ALLOC(srv) < 0) {
virReportOOMError(); virReportOOMError();
@ -434,20 +497,25 @@ virNetlinkEventServiceStart(void)
goto error_locked; goto error_locked;
} }
if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) { if (nl_connect(srv->netlinknh, protocol) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
"%s", _("cannot connect to netlink socket")); _("cannot connect to netlink socket with protocol %d"), protocol);
goto error_server; goto error_server;
} }
fd = nl_socket_get_fd(srv->netlinknh); fd = nl_socket_get_fd(srv->netlinknh);
if (fd < 0) { if (fd < 0) {
virReportSystemError(errno, virReportSystemError(errno,
"%s", _("cannot get netlink socket fd")); "%s", _("cannot get netlink socket fd"));
goto error_server; 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)) { if (nl_socket_set_nonblocking(srv->netlinknh)) {
virReportSystemError(errno, "%s", virReportSystemError(errno, "%s",
_("cannot set netlink socket nonblocking")); _("cannot set netlink socket nonblocking"));
@ -467,7 +535,7 @@ virNetlinkEventServiceStart(void)
VIR_DEBUG("netlink event listener on fd: %i running", fd); VIR_DEBUG("netlink event listener on fd: %i running", fd);
ret = 0; ret = 0;
server = srv; server[protocol] = srv;
error_server: error_server:
if (ret < 0) { if (ret < 0) {
@ -491,6 +559,7 @@ error_locked:
* @opaque: user data to pass to callback * @opaque: user data to pass to callback
* @macaddr: macaddr to store with the data. Used to identify callers. * @macaddr: macaddr to store with the data. Used to identify callers.
* May be null. * May be null.
* @protocol: netlink protocol
* *
* register a callback for handling of netlink messages. The * register a callback for handling of netlink messages. The
* registered function receives the entire netlink message and * registered function receives the entire netlink message and
@ -502,10 +571,16 @@ error_locked:
int int
virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB, virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
virNetlinkEventRemoveCallback removeCB, virNetlinkEventRemoveCallback removeCB,
void *opaque, const virMacAddrPtr macaddr) void *opaque, const virMacAddrPtr macaddr,
unsigned int protocol)
{ {
int i, r, ret = -1; int i, r, ret = -1;
virNetlinkEventSrvPrivatePtr srv = server; virNetlinkEventSrvPrivatePtr srv = NULL;
if (protocol >= MAX_LINKS)
return -EINVAL;
srv = server[protocol];
if (handleCB == NULL) { if (handleCB == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -562,6 +637,7 @@ error:
* *
* @watch: watch whose handle to remove * @watch: watch whose handle to remove
* @macaddr: macaddr whose handle to remove * @macaddr: macaddr whose handle to remove
* @protocol: netlink protocol
* *
* Unregister a callback from a netlink monitor. * Unregister a callback from a netlink monitor.
* The handler function referenced will no longer receive netlink messages. * The handler function referenced will no longer receive netlink messages.
@ -570,11 +646,17 @@ error:
* Returns -1 if the file handle was not registered, 0 upon success * Returns -1 if the file handle was not registered, 0 upon success
*/ */
int int
virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr) virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
unsigned int protocol)
{ {
int i; int i;
int ret = -1; 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); VIR_DEBUG("removing client watch=%d, mac=%p.", watch, macaddr);
@ -595,7 +677,7 @@ virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr)
VIR_DEBUG("removed client: %d by %s.", VIR_DEBUG("removed client: %d by %s.",
srv->handles[i].watch, watch ? "index" : "mac"); srv->handles[i].watch, watch ? "index" : "mac");
virNetlinkEventRemoveClientPrimitive(i); virNetlinkEventRemoveClientPrimitive(i, protocol);
ret = 0; ret = 0;
goto cleanup; goto cleanup;
} }
@ -631,7 +713,9 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
unsigned char **respbuf ATTRIBUTE_UNUSED, unsigned char **respbuf ATTRIBUTE_UNUSED,
unsigned int *respbuflen ATTRIBUTE_UNUSED, unsigned int *respbuflen ATTRIBUTE_UNUSED,
uint32_t src_pid 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)); virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1; return -1;
@ -641,7 +725,7 @@ int virNetlinkCommand(struct nl_msg *nl_msg ATTRIBUTE_UNUSED,
* stopNetlinkEventServer: stop the monitor to receive netlink * stopNetlinkEventServer: stop the monitor to receive netlink
* messages for libvirtd * messages for libvirtd
*/ */
int virNetlinkEventServiceStop(void) int virNetlinkEventServiceStop(unsigned int protocol ATTRIBUTE_UNUSED)
{ {
VIR_DEBUG("%s", _(unsupported)); VIR_DEBUG("%s", _(unsupported));
return 0; return 0;
@ -651,7 +735,8 @@ int virNetlinkEventServiceStop(void)
* startNetlinkEventServer: start a monitor to receive netlink * startNetlinkEventServer: start a monitor to receive netlink
* messages for libvirtd * messages for libvirtd
*/ */
int virNetlinkEventServiceStart(void) int virNetlinkEventServiceStart(unsigned int protocol ATTRIBUTE_UNUSED,
unsigned int groups ATTRIBUTE_UNUSED)
{ {
VIR_DEBUG("%s", _(unsupported)); VIR_DEBUG("%s", _(unsupported));
return 0; return 0;
@ -661,13 +746,13 @@ int virNetlinkEventServiceStart(void)
* virNetlinkEventServiceIsRunning: returns if the netlink event * virNetlinkEventServiceIsRunning: returns if the netlink event
* service is running. * service is running.
*/ */
bool virNetlinkEventServiceIsRunning(void) bool virNetlinkEventServiceIsRunning(unsigned int protocol ATTRIBUTE_UNUSED)
{ {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return 0; return 0;
} }
int virNetlinkEventServiceLocalPid(void) int virNetlinkEventServiceLocalPid(unsigned int protocol ATTRIBUTE_UNUSED)
{ {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1; return -1;
@ -681,6 +766,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UN
virNetlinkEventRemoveCallback removeCB ATTRIBUTE_UNUSED, virNetlinkEventRemoveCallback removeCB ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED, void *opaque ATTRIBUTE_UNUSED,
const virMacAddrPtr macaddr ATTRIBUTE_UNUSED) const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)
unsigned int protocol ATTRIBUTE_UNUSED)
{ {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1; return -1;
@ -691,6 +777,7 @@ int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UN
*/ */
int virNetlinkEventRemoveClient(int watch ATTRIBUTE_UNUSED, int virNetlinkEventRemoveClient(int watch ATTRIBUTE_UNUSED,
const virMacAddrPtr macaddr ATTRIBUTE_UNUSED) const virMacAddrPtr macaddr ATTRIBUTE_UNUSED)
unsigned int protocol ATTRIBUTE_UNUSED)
{ {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported)); virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1; return -1;

View File

@ -41,7 +41,8 @@ void virNetlinkShutdown(void);
int virNetlinkCommand(struct nl_msg *nl_msg, int virNetlinkCommand(struct nl_msg *nl_msg,
unsigned char **respbuf, unsigned int *respbuflen, 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); 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 * 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 * 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. * 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 * 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 * virNetlinkEventAddClient: register a callback for handling of netlink messages
*/ */
int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB, int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
virNetlinkEventRemoveCallback removeCB, virNetlinkEventRemoveCallback removeCB,
void *opaque, const virMacAddrPtr macaddr); void *opaque, const virMacAddrPtr macaddr,
unsigned int protocol);
/** /**
* virNetlinkEventRemoveClient: unregister a callback from a netlink monitor * 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__ */ #endif /* __VIR_NETLINK_H__ */