13
13
* Lesser General Public License for more details.
15
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
* License along with this library. If not, see
17
* <http://www.gnu.org/licenses/>.
20
20
* Stefan Berger <stefanb@us.ibm.com>
41
42
#include "virmacaddr.h"
42
43
#include "virterror_internal.h"
46
# define SOL_NETLINK 270
44
49
#define VIR_FROM_THIS VIR_FROM_NET
46
#define netlinkError(code, ...) \
47
virReportErrorHelper(VIR_FROM_NET, code, __FILE__, \
48
__FUNCTION__, __LINE__, __VA_ARGS__)
50
51
#define NETLINK_ACK_TIMEOUT_S 2
52
53
#if defined(__linux__) && defined(HAVE_LIBNL)
97
98
records in this multiple */
98
99
# define NETLINK_EVENT_ALLOC_EXTENT 10
100
static virNetlinkEventSrvPrivatePtr server = NULL;
101
/* Linux kernel supports up to MAX_LINKS (32 at the time) individual
102
* netlink protocols. */
103
static virNetlinkEventSrvPrivatePtr server[MAX_LINKS] = {NULL};
101
104
static virNetlinkHandle *placeholder_nlhandle = NULL;
103
106
/* Function definitions */
161
164
* @respbuf: pointer to pointer where response buffer will be allocated
162
165
* @respbuflen: pointer to integer holding the size of the response buffer
163
166
* on return of the function.
164
* @nl_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
167
* @src_pid: the pid of the process to send a message
168
* @dst_pid: the pid of the process to talk to, i.e., pid = 0 for kernel
169
* @protocol: netlink protocol
170
* @groups: the group identifier
166
172
* Send the given message to the netlink layer and receive response.
167
173
* Returns 0 on success, -1 on error. In case of error, no response
170
176
int virNetlinkCommand(struct nl_msg *nl_msg,
171
177
unsigned char **respbuf, unsigned int *respbuflen,
172
uint32_t src_pid, uint32_t dst_pid)
178
uint32_t src_pid, uint32_t dst_pid,
179
unsigned int protocol, unsigned int groups)
175
182
struct sockaddr_nl nladdr = {
187
194
struct nlmsghdr *nlmsg = nlmsg_hdr(nl_msg);
188
virNetlinkHandle *nlhandle = virNetlinkAlloc();
195
virNetlinkHandle *nlhandle = NULL;
197
if (protocol >= MAX_LINKS) {
198
virReportSystemError(EINVAL,
199
_("invalid protocol argument: %d"), protocol);
203
nlhandle = virNetlinkAlloc();
191
205
virReportSystemError(errno,
192
206
"%s", _("cannot allocate nlhandle for netlink"));
196
if (nl_connect(nlhandle, NETLINK_ROUTE) < 0) {
197
virReportSystemError(errno,
198
"%s", _("cannot connect to netlink socket"));
210
if (nl_connect(nlhandle, protocol) < 0) {
211
virReportSystemError(errno,
212
_("cannot connect to netlink socket with protocol %d"),
218
fd = nl_socket_get_fd(nlhandle);
220
virReportSystemError(errno,
221
"%s", _("cannot get netlink socket fd"));
226
if (groups && nl_socket_add_membership(nlhandle, groups) < 0) {
227
virReportSystemError(errno,
228
"%s", _("cannot add netlink membership"));
272
301
* assumes success, returns nothing.
275
virNetlinkEventRemoveClientPrimitive(size_t i)
304
virNetlinkEventRemoveClientPrimitive(size_t i, unsigned int protocol)
277
virNetlinkEventRemoveCallback removeCB = server->handles[i].removeCB;
306
if (protocol >= MAX_LINKS)
309
virNetlinkEventRemoveCallback removeCB = server[protocol]->handles[i].removeCB;
280
(removeCB)(server->handles[i].watch,
281
server->handles[i].macaddr,
282
server->handles[i].opaque);
312
(removeCB)(server[protocol]->handles[i].watch,
313
&server[protocol]->handles[i].macaddr,
314
server[protocol]->handles[i].opaque);
284
server->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
316
server[protocol]->handles[i].deleted = VIR_NETLINK_HANDLE_DELETED;
334
367
* stop the monitor to receive netlink messages for libvirtd.
335
368
* This removes the netlink socket fd from the event handler.
370
* @protocol: netlink protocol
337
372
* Returns -1 if the monitor cannot be unregistered, 0 upon success
340
virNetlinkEventServiceStop(void)
375
virNetlinkEventServiceStop(unsigned int protocol)
342
virNetlinkEventSrvPrivatePtr srv = server;
377
if (protocol >= MAX_LINKS)
380
virNetlinkEventSrvPrivatePtr srv = server[protocol];
345
383
VIR_INFO("stopping netlink event service");
385
if (!server[protocol])
350
388
virNetlinkEventServerLock(srv);
355
393
/* free any remaining clients on the list */
356
394
for (i = 0; i < srv->handlesCount; i++) {
357
395
if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID)
358
virNetlinkEventRemoveClientPrimitive(i);
396
virNetlinkEventRemoveClientPrimitive(i, protocol);
399
server[protocol] = NULL;
362
400
virNetlinkEventServerUnlock(srv);
364
402
virMutexDestroy(&srv->lock);
408
* virNetlinkEventServiceStopAll:
410
* Stop all the monitors to receive netlink messages for libvirtd.
412
* Returns -1 if any monitor cannot be unregistered, 0 upon success
415
virNetlinkEventServiceStopAll(void)
418
virNetlinkEventSrvPrivatePtr srv = NULL;
420
VIR_INFO("stopping all netlink event services");
422
for (i = 0; i < MAX_LINKS; i++) {
427
virNetlinkEventServerLock(srv);
428
nl_close(srv->netlinknh);
429
virNetlinkFree(srv->netlinknh);
430
virEventRemoveHandle(srv->eventwatch);
432
for (j = 0; j < srv->handlesCount; j++) {
433
if (srv->handles[j].deleted == VIR_NETLINK_HANDLE_VALID)
434
virNetlinkEventRemoveClientPrimitive(j, i);
438
virNetlinkEventServerUnlock(srv);
440
virMutexDestroy(&srv->lock);
370
448
* virNetlinkEventServiceIsRunning:
372
450
* Returns if the netlink event service is running.
452
* @protocol: netlink protocol
374
454
* Returns 'true' if the service is running, 'false' if stopped.
377
virNetlinkEventServiceIsRunning(void)
457
virNetlinkEventServiceIsRunning(unsigned int protocol)
379
return server != NULL;
459
if (protocol >= MAX_LINKS) {
460
virReportSystemError(EINVAL,
461
_("invalid protocol argument: %d"), protocol);
465
return server[protocol] != NULL;
383
469
* virNetlinkEventServiceLocalPid:
471
* @protocol: netlink protocol
385
473
* Returns the nl_pid value that was used to bind() the netlink socket
386
474
* used by the netlink event service, or -1 on error (netlink
387
475
* guarantees that this value will always be > 0).
389
int virNetlinkEventServiceLocalPid(void)
477
int virNetlinkEventServiceLocalPid(unsigned int protocol)
391
if (!(server && server->netlinknh)) {
392
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
393
_("netlink event service not running"));
479
if (protocol >= MAX_LINKS)
482
if (!(server[protocol] && server[protocol]->netlinknh)) {
483
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
484
_("netlink event service not running"));
396
return (int)nl_socket_get_local_port(server->netlinknh);
487
return (int)nl_socket_get_local_port(server[protocol]->netlinknh);
403
494
* start a monitor to receive netlink messages for libvirtd.
404
495
* This registers a netlink socket with the event interface.
497
* @protocol: netlink protocol
498
* @groups: broadcast groups to join in
406
499
* Returns -1 if the monitor cannot be registered, 0 upon success
409
virNetlinkEventServiceStart(void)
502
virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
411
504
virNetlinkEventSrvPrivatePtr srv;
508
if (protocol >= MAX_LINKS) {
509
virReportSystemError(EINVAL,
510
_("invalid protocol argument: %d"), protocol);
514
if (server[protocol])
418
VIR_INFO("starting netlink event service");
517
VIR_INFO("starting netlink event service with protocol %d", protocol);
420
519
if (VIR_ALLOC(srv) < 0) {
421
520
virReportOOMError();
438
537
goto error_locked;
441
if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) {
540
if (nl_connect(srv->netlinknh, protocol) < 0) {
442
541
virReportSystemError(errno,
443
"%s", _("cannot connect to netlink socket"));
542
_("cannot connect to netlink socket with protocol %d"), protocol);
444
543
goto error_server;
447
546
fd = nl_socket_get_fd(srv->netlinknh);
450
548
virReportSystemError(errno,
451
549
"%s", _("cannot get netlink socket fd"));
452
550
goto error_server;
553
if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) {
554
virReportSystemError(errno,
555
"%s", _("cannot add netlink membership"));
455
559
if (nl_socket_set_nonblocking(srv->netlinknh)) {
456
560
virReportSystemError(errno, "%s",
457
561
_("cannot set netlink socket nonblocking"));
462
566
VIR_EVENT_HANDLE_READABLE,
463
567
virNetlinkEventCallback,
464
568
srv, NULL)) < 0) {
465
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
466
_("Failed to add netlink event handle watch"));
569
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
570
_("Failed to add netlink event handle watch"));
467
571
goto error_server;
507
612
virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB,
508
613
virNetlinkEventRemoveCallback removeCB,
509
void *opaque, const unsigned char *macaddr)
614
void *opaque, const virMacAddrPtr macaddr,
615
unsigned int protocol)
511
617
int i, r, ret = -1;
512
virNetlinkEventSrvPrivatePtr srv = server;
618
virNetlinkEventSrvPrivatePtr srv = NULL;
620
if (protocol >= MAX_LINKS)
623
srv = server[protocol];
514
625
if (handleCB == NULL) {
515
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
516
_("Invalid NULL callback provided"));
626
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
627
_("Invalid NULL callback provided"));
548
659
srv->handles[r].opaque = opaque;
549
660
srv->handles[r].deleted = VIR_NETLINK_HANDLE_VALID;
551
memcpy(srv->handles[r].macaddr, macaddr, VIR_MAC_BUFLEN);
662
virMacAddrSet(&srv->handles[r].macaddr, macaddr);
553
memset(srv->handles[r].macaddr, 0, VIR_MAC_BUFLEN);
664
virMacAddrSetRaw(&srv->handles[r].macaddr,
665
(unsigned char[VIR_MAC_BUFLEN]){0,0,0,0,0,0});
555
667
VIR_DEBUG("added client to loop slot: %d. with macaddr ptr=%p", r, macaddr);
573
686
* Returns -1 if the file handle was not registered, 0 upon success
576
virNetlinkEventRemoveClient(int watch, const unsigned char *macaddr)
689
virNetlinkEventRemoveClient(int watch, const virMacAddrPtr macaddr,
690
unsigned int protocol)
580
virNetlinkEventSrvPrivatePtr srv = server;
694
virNetlinkEventSrvPrivatePtr srv = NULL;
696
if (protocol >= MAX_LINKS)
699
srv = server[protocol];
582
701
VIR_DEBUG("removing client watch=%d, mac=%p.", watch, macaddr);
595
714
if ((watch && srv->handles[i].watch == watch) ||
597
memcmp(macaddr, srv->handles[i].macaddr, VIR_MAC_BUFLEN) == 0)) {
716
virMacAddrCmp(macaddr, &srv->handles[i].macaddr) == 0)) {
599
718
VIR_DEBUG("removed client: %d by %s.",
600
719
srv->handles[i].watch, watch ? "index" : "mac");
601
virNetlinkEventRemoveClientPrimitive(i);
720
virNetlinkEventRemoveClientPrimitive(i, protocol);
634
753
unsigned char **respbuf ATTRIBUTE_UNUSED,
635
754
unsigned int *respbuflen ATTRIBUTE_UNUSED,
636
755
uint32_t src_pid ATTRIBUTE_UNUSED,
637
uint32_t dst_pid ATTRIBUTE_UNUSED)
756
uint32_t dst_pid ATTRIBUTE_UNUSED,
757
unsigned int protocol ATTRIBUTE_UNUSED,
758
unsigned int groups ATTRIBUTE_UNUSED)
639
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
760
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
644
765
* stopNetlinkEventServer: stop the monitor to receive netlink
645
766
* messages for libvirtd
647
int virNetlinkEventServiceStop(void)
768
int virNetlinkEventServiceStop(unsigned int protocol ATTRIBUTE_UNUSED)
770
VIR_DEBUG("%s", _(unsupported));
775
* stopNetlinkEventServerAll: stop all the monitors to receive netlink
776
* messages for libvirtd
778
int virNetlinkEventServiceStopAll(void)
649
780
VIR_DEBUG("%s", _(unsupported));
664
796
* virNetlinkEventServiceIsRunning: returns if the netlink event
665
797
* service is running.
667
bool virNetlinkEventServiceIsRunning(void)
799
bool virNetlinkEventServiceIsRunning(unsigned int protocol ATTRIBUTE_UNUSED)
669
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
801
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
673
int virNetlinkEventServiceLocalPid(void)
805
int virNetlinkEventServiceLocalPid(unsigned int protocol ATTRIBUTE_UNUSED)
675
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
807
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
683
815
int virNetlinkEventAddClient(virNetlinkEventHandleCallback handleCB ATTRIBUTE_UNUSED,
684
816
virNetlinkEventRemoveCallback removeCB ATTRIBUTE_UNUSED,
685
817
void *opaque ATTRIBUTE_UNUSED,
686
const unsigned char *macaddr ATTRIBUTE_UNUSED)
818
const virMacAddrPtr macaddr ATTRIBUTE_UNUSED,
819
unsigned int protocol ATTRIBUTE_UNUSED)
688
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
821
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
693
826
* virNetlinkEventRemoveClient: unregister a callback from a netlink monitor
695
828
int virNetlinkEventRemoveClient(int watch ATTRIBUTE_UNUSED,
696
const unsigned char *macaddr ATTRIBUTE_UNUSED)
829
const virMacAddrPtr macaddr ATTRIBUTE_UNUSED,
830
unsigned int protocol ATTRIBUTE_UNUSED)
698
netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
832
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));