projects
/
openvswitch
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ovs.json: Optimize __dump_string().
[openvswitch]
/
lib
/
rtnetlink.c
diff --git
a/lib/rtnetlink.c
b/lib/rtnetlink.c
index 5d80d7258fa3ea2009f00e11391d4f4821e050e0..b600554390ee162d1b0d67e8f4d1dc8ddb76caa9 100644
(file)
--- a/
lib/rtnetlink.c
+++ b/
lib/rtnetlink.c
@@
-1,5
+1,5
@@
/*
/*
- * Copyright (c) 2009, 2010 Nicira Networks.
+ * Copyright (c) 2009, 2010
, 2011
Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@
-20,6
+20,7
@@
#include <errno.h>
#include <poll.h>
#include <errno.h>
#include <poll.h>
+#include <stdlib.h>
#include "coverage.h"
#include "netlink.h"
#include "coverage.h"
#include "netlink.h"
@@
-36,6
+37,7
@@
static void rtnetlink_report(struct rtnetlink *rtn, void *change);
struct rtnetlink {
struct nl_sock *notify_sock; /* Rtnetlink socket. */
struct list all_notifiers; /* All rtnetlink notifiers. */
struct rtnetlink {
struct nl_sock *notify_sock; /* Rtnetlink socket. */
struct list all_notifiers; /* All rtnetlink notifiers. */
+ bool has_run; /* Guard for run and wait functions. */
/* Passed in by rtnetlink_create(). */
int multicast_group; /* Multicast group we listen on. */
/* Passed in by rtnetlink_create(). */
int multicast_group; /* Multicast group we listen on. */
@@
-54,15
+56,27
@@
rtnetlink_create(int multicast_group, rtnetlink_parse_func *parse,
struct rtnetlink *rtn;
rtn = xzalloc(sizeof *rtn);
struct rtnetlink *rtn;
rtn = xzalloc(sizeof *rtn);
- rtn->notify_sock =
0
;
+ rtn->notify_sock =
NULL
;
rtn->multicast_group = multicast_group;
rtn->parse = parse;
rtn->change = change;
rtn->multicast_group = multicast_group;
rtn->parse = parse;
rtn->change = change;
+ rtn->has_run = false;
list_init(&rtn->all_notifiers);
return rtn;
}
list_init(&rtn->all_notifiers);
return rtn;
}
+/* Destroys 'rtn' by freeing any memory it has reserved and closing any sockets
+ * it has opened. */
+void
+rtnetlink_destroy(struct rtnetlink *rtn)
+{
+ if (rtn) {
+ nl_sock_destroy(rtn->notify_sock);
+ free(rtn);
+ }
+}
+
/* Registers 'cb' to be called with auxiliary data 'aux' with change
* notifications. The notifier is stored in 'notifier', which the caller must
* not modify or free.
/* Registers 'cb' to be called with auxiliary data 'aux' with change
* notifications. The notifier is stored in 'notifier', which the caller must
* not modify or free.
@@
-77,13
+91,20
@@
rtnetlink_notifier_register(struct rtnetlink *rtn,
rtnetlink_notify_func *cb, void *aux)
{
if (!rtn->notify_sock) {
rtnetlink_notify_func *cb, void *aux)
{
if (!rtn->notify_sock) {
- int error = nl_sock_create(NETLINK_ROUTE, rtn->multicast_group, 0, 0,
- &rtn->notify_sock);
+ struct nl_sock *sock;
+ int error;
+
+ error = nl_sock_create(NETLINK_ROUTE, &sock);
+ if (!error) {
+ error = nl_sock_join_mcgroup(sock, rtn->multicast_group);
+ }
if (error) {
if (error) {
+ nl_sock_destroy(sock);
VLOG_WARN("could not create rtnetlink socket: %s",
strerror(error));
return error;
}
VLOG_WARN("could not create rtnetlink socket: %s",
strerror(error));
return error;
}
+ rtn->notify_sock = sock;
} else {
/* Catch up on notification work so that the new notifier won't
* receive any stale notifications. */
} else {
/* Catch up on notification work so that the new notifier won't
* receive any stale notifications. */
@@
-116,10
+137,11
@@
rtnetlink_notifier_run(struct rtnetlink *rtn)
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
- if (!rtn->notify_sock) {
+ if (!rtn->notify_sock
|| rtn->has_run
) {
return;
}
return;
}
+ rtn->has_run = true;
for (;;) {
struct ofpbuf *buf;
int error;
for (;;) {
struct ofpbuf *buf;
int error;
@@
-151,6
+173,7
@@
rtnetlink_notifier_run(struct rtnetlink *rtn)
void
rtnetlink_notifier_wait(struct rtnetlink *rtn)
{
void
rtnetlink_notifier_wait(struct rtnetlink *rtn)
{
+ rtn->has_run = false;
if (rtn->notify_sock) {
nl_sock_wait(rtn->notify_sock, POLLIN);
}
if (rtn->notify_sock) {
nl_sock_wait(rtn->notify_sock, POLLIN);
}