]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Cleanup igmp read socket
authorDonald Sharp <sharpd@cumulusnetworks.com>
Sat, 19 Nov 2016 16:20:26 +0000 (11:20 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:16 +0000 (20:26 -0500)
With the change over to using the kernel upcall for igmp messages,
we need to add in a read thread for the igmp socket to drain
the igmp socket's receive queue.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_igmp.c
pimd/pim_sock.c

index f47028b2baf7999e407b9044cd347a515a8f0f96..87a54d68d0e06d3ddce044e7d7c1bfe616206d88 100644 (file)
@@ -665,7 +665,6 @@ static void sock_close(struct igmp_sock *igmp)
     }
   }
   THREAD_OFF(igmp->t_igmp_read);
-  zassert(!igmp->t_igmp_read);
   
   if (close(igmp->fd)) {
     zlog_err("Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
@@ -841,6 +840,58 @@ static struct igmp_sock *igmp_sock_new(int fd,
   return igmp;
 }
 
+static void igmp_read_on (struct igmp_sock *igmp);
+
+static int
+pim_igmp_read (struct thread *t)
+{
+  uint8_t buf[10000];
+  struct igmp_sock *igmp = (struct igmp_sock *)THREAD_ARG(t);
+  struct sockaddr_in from;
+  struct sockaddr_in to;
+  socklen_t fromlen = sizeof(from);
+  socklen_t tolen = sizeof(to);
+  ifindex_t ifindex = -1;
+  int cont = 1;
+  int len;
+
+  while (cont)
+    {
+      len = pim_socket_recvfromto(igmp->fd, buf, sizeof(buf),
+                                 &from, &fromlen,
+                                 &to, &tolen,
+                                 &ifindex);
+      if (len < 0)
+       {
+         if (errno == EINTR)
+           continue;
+         if (errno == EWOULDBLOCK || errno == EAGAIN)
+         {
+           cont = 0;
+           break;
+         }
+         goto done;
+       }
+    }
+
+ done:
+  igmp_read_on(igmp);
+  return 0;
+}
+
+static void
+igmp_read_on (struct igmp_sock *igmp)
+{
+
+  if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
+    zlog_debug("Scheduling READ event on IGMP socket fd=%d",
+              igmp->fd);
+  }
+  igmp->t_igmp_read = NULL;
+  THREAD_READ_ON(master, igmp->t_igmp_read, pim_igmp_read, igmp, igmp->fd);
+
+}
+
 struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
                                    struct in_addr ifaddr,
                                    struct interface *ifp)
@@ -866,6 +917,8 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
     return 0;
   }
 
+  igmp_read_on (igmp);
+
   listnode_add(igmp_sock_list, igmp);
 
 #ifdef IGMP_SOCK_DUMP
index 6ce336d605a222fc35c49054355ea3b629b466ff..12f222bb80dd40935be23fe6a5c1745bd495335d 100644 (file)
@@ -230,25 +230,24 @@ int pim_socket_mcast(int protocol, struct in_addr ifaddr, int ifindex, u_char lo
       zlog_warn("%s: Failure to set buffer size to %d",
                __PRETTY_FUNCTION__, rcvbuf);
 
-  if (protocol == IPPROTO_PIM)
-    {
-      long flags;
-
-      flags = fcntl(fd, F_GETFL, 0);
-      if (flags < 0) {
-       zlog_warn("Could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
-                 fd, errno, safe_strerror(errno));
-       close(fd);
-       return PIM_SOCK_ERR_NONBLOCK_GETFL;
-      }
+  {
+    long flags;
 
-      if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
-       zlog_warn("Could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
-                 fd, errno, safe_strerror(errno));
-       close(fd);
-       return PIM_SOCK_ERR_NONBLOCK_SETFL;
-      }
+    flags = fcntl(fd, F_GETFL, 0);
+    if (flags < 0) {
+      zlog_warn("Could not get fcntl(F_GETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+               fd, errno, safe_strerror(errno));
+      close(fd);
+      return PIM_SOCK_ERR_NONBLOCK_GETFL;
+    }
+
+    if (fcntl(fd, F_SETFL, flags | O_NONBLOCK)) {
+      zlog_warn("Could not set fcntl(F_SETFL,O_NONBLOCK) on socket fd=%d: errno=%d: %s",
+               fd, errno, safe_strerror(errno));
+      close(fd);
+      return PIM_SOCK_ERR_NONBLOCK_SETFL;
     }
+  }
 
   return fd;
 }