ovs.db.types: Use toAtomicType() instead of open-coding it.
[sliver-openvswitch.git] / lib / rtnetlink.c
index cc175b4..b600554 100644 (file)
@@ -37,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. */
+    bool has_run;                /* Guard for run and wait functions. */
 
     /* Passed in by rtnetlink_create(). */
     int multicast_group;         /* Multicast group we listen on. */
@@ -55,10 +56,11 @@ rtnetlink_create(int multicast_group, rtnetlink_parse_func *parse,
     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->has_run         = false;
 
     list_init(&rtn->all_notifiers);
     return rtn;
@@ -89,13 +91,20 @@ rtnetlink_notifier_register(struct rtnetlink *rtn,
                             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) {
+            nl_sock_destroy(sock);
             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. */
@@ -128,10 +137,11 @@ rtnetlink_notifier_run(struct rtnetlink *rtn)
 {
     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
 
-    if (!rtn->notify_sock) {
+    if (!rtn->notify_sock || rtn->has_run) {
         return;
     }
 
+    rtn->has_run = true;
     for (;;) {
         struct ofpbuf *buf;
         int error;
@@ -163,6 +173,7 @@ rtnetlink_notifier_run(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);
     }