]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Fixup kernel callbacks to handle them better
authorDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 20 Oct 2015 13:00:02 +0000 (06:00 -0700)
committerDonald Sharp <sharpd@cumulusnetwroks.com>
Thu, 26 May 2016 00:38:34 +0000 (20:38 -0400)
This patch sets up the handling of the 3 basic kernel callbacks:
IGMPMSG_WRONGVIF - When a multicast message comes in the wrong vif
IGMPMSG_NOCACHE - There is no multicast route associated with a received(S,G)
IGMPMSG_WHOLEPKT - There is no outgoing interface for a packet.

The code's debugs are cleaned up to be covered by debug statements

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

index 2f04323db20e19eaf9fcd1442a769fb7f4c7fd76..f0830c1e7b2050c0753d2d1688e2ae0ddcf6011c 100644 (file)
@@ -61,135 +61,169 @@ static int pim_mroute_set(int fd, int enable)
   return 0;
 }
 
-int pim_mroute_msg(int fd, const char *buf, int buf_size)
+static const char *igmpmsgtype2str[IGMPMSG_WHOLEPKT + 1] = {
+  "<unknown_upcall?>",
+  "NOCACHE",
+  "WRONGVIF",
+  "WHOLEPKT", };
+
+static int
+pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg,
+                       const char *src_str, const char *grp_str)
 {
-  struct interface     *ifp;
-  const struct ip      *ip_hdr;
-  const struct igmpmsg *msg;
-  const char *upcall;
-  char src_str[100];
-  char grp_str[100];
+  return 0;
+}
 
-  ip_hdr = (const struct ip *) buf;
+static int
+pim_mroute_msg_wholepkt (int fd, struct interface *ifp, const struct igmpmsg *msg,
+                        const char *src_str, const char *grp_str)
+{
+  return 0;
+}
 
-  /* kernel upcall must have protocol=0 */
-  if (ip_hdr->ip_p) {
-    /* this is not a kernel upcall */
-#ifdef PIM_UNEXPECTED_KERNEL_UPCALL
-    zlog_warn("%s: not a kernel upcall proto=%d msg_size=%d",
-             __PRETTY_FUNCTION__, ip_hdr->ip_p, buf_size);
-#endif
-    return 0;
-  }
+static int
+pim_mroute_msg_wrongvif (int fd, struct interface *ifp, const struct igmpmsg *msg,
+                        const char *src_str, const char *grp_str)
+{
+  struct pim_ifchannel *ch;
+  struct pim_interface *pim_ifp;
 
-  msg = (const struct igmpmsg *) buf;
+  /*
+    Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
 
-  switch (msg->im_msgtype) {
-  case IGMPMSG_NOCACHE:  upcall = "NOCACHE";  break;
-  case IGMPMSG_WRONGVIF: upcall = "WRONGVIF"; break;
-  case IGMPMSG_WHOLEPKT: upcall = "WHOLEPKT"; break;
-  default: upcall = "<unknown_upcall?>";
-  }
-  ifp = pim_if_find_by_vif_index(msg->im_vif);
-  pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
-  pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
-    
-  if (msg->im_msgtype == IGMPMSG_WRONGVIF) {
-    struct pim_ifchannel *ch;
-    struct pim_interface *pim_ifp;
-
-    /*
-      Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
-      
-      RFC 4601 4.8.2.  PIM-SSM-Only Routers
-      
-      iif is the incoming interface of the packet.
-      if (iif is in inherited_olist(S,G)) {
-      send Assert(S,G) on iif
-      }
-    */
+    RFC 4601 4.8.2.  PIM-SSM-Only Routers
+
+    iif is the incoming interface of the packet.
+    if (iif is in inherited_olist(S,G)) {
+    send Assert(S,G) on iif
+    }
+  */
 
+  if (!ifp) {
     if (PIM_DEBUG_PIM_TRACE) {
-      zlog_debug("%s: WRONGVIF from fd=%d for (S,G)=(%s,%s) on %s vifi=%d",
+      zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) could not find input interface for input_vif_index=%d",
                 __PRETTY_FUNCTION__,
-                fd,
-                src_str,
-                grp_str,
-                ifp ? ifp->name : "<ifname?>",
-                msg->im_vif);
+                src_str, grp_str, msg->im_vif);
     }
+    return -1;
+  }
 
-    if (!ifp) {
-      zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) could not find input interface for input_vif_index=%d",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, msg->im_vif);
-      return -1;
+  pim_ifp = ifp->info;
+  if (!pim_ifp) {
+    if (PIM_DEBUG_PIM_TRACE) {
+      zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) multicast not enabled on interface %s",
+                __PRETTY_FUNCTION__,
+                src_str, grp_str, ifp->name);
     }
+    return -2;
+  }
 
-    pim_ifp = ifp->info;
-    if (!pim_ifp) {
-      zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) multicast not enabled on interface %s",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, ifp->name);
-      return -2;
+  ch = pim_ifchannel_find(ifp, msg->im_src, msg->im_dst);
+  if (!ch) {
+    if (PIM_DEBUG_PIM_TRACE) {
+      zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) could not find channel on interface %s",
+                __PRETTY_FUNCTION__,
+                src_str, grp_str, ifp->name);
     }
+    return -3;
+  }
 
-    ch = pim_ifchannel_find(ifp, msg->im_src, msg->im_dst);
-    if (!ch) {
-      zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) could not find channel on interface %s",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, ifp->name);
-      return -3;
-    }
+  /*
+    RFC 4601: 4.6.1.  (S,G) Assert Message State Machine
+
+    Transitions from NoInfo State
+
+    An (S,G) data packet arrives on interface I, AND
+    CouldAssert(S,G,I)==TRUE An (S,G) data packet arrived on an
+    downstream interface that is in our (S,G) outgoing interface
+    list.  We optimistically assume that we will be the assert
+    winner for this (S,G), and so we transition to the "I am Assert
+    Winner" state and perform Actions A1 (below), which will
+    initiate the assert negotiation for (S,G).
+  */
 
-    /*
-      RFC 4601: 4.6.1.  (S,G) Assert Message State Machine
-
-      Transitions from NoInfo State
-
-      An (S,G) data packet arrives on interface I, AND
-      CouldAssert(S,G,I)==TRUE An (S,G) data packet arrived on an
-      downstream interface that is in our (S,G) outgoing interface
-      list.  We optimistically assume that we will be the assert
-      winner for this (S,G), and so we transition to the "I am Assert
-      Winner" state and perform Actions A1 (below), which will
-      initiate the assert negotiation for (S,G).
-    */
-
-    if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
-      zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) channel is not on Assert NoInfo state for interface %s",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, ifp->name);
-      return -4;
+  if (ch->ifassert_state != PIM_IFASSERT_NOINFO) {
+    if (PIM_DEBUG_PIM_TRACE) {
+      zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) channel is not on Assert NoInfo state for interface %s",
+                __PRETTY_FUNCTION__,
+                src_str, grp_str, ifp->name);
     }
+    return -4;
+  }
 
-    if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
-      zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) interface %s is not downstream for channel",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, ifp->name);
-      return -5;
+  if (!PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags)) {
+    if (PIM_DEBUG_PIM_TRACE) {
+      zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) interface %s is not downstream for channel",
+                __PRETTY_FUNCTION__,
+                src_str, grp_str, ifp->name);
     }
+    return -5;
+  }
 
-    if (assert_action_a1(ch)) {
-      zlog_warn("%s: WRONGVIF (S,G)=(%s,%s) assert_action_a1 failure on interface %s",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, ifp->name);
-      return -6;
+  if (assert_action_a1(ch)) {
+    if (PIM_DEBUG_PIM_TRACE) {
+      zlog_debug("%s: WRONGVIF (S,G)=(%s,%s) assert_action_a1 failure on interface %s",
+                __PRETTY_FUNCTION__,
+                src_str, grp_str, ifp->name);
     }
+    return -6;
+  }
+
+  return 0;
+}
+
+int pim_mroute_msg(int fd, const char *buf, int buf_size)
+{
+  struct interface     *ifp;
+  const struct ip      *ip_hdr;
+  const struct igmpmsg *msg;
+  char src_str[100] = "<src?>";
+  char grp_str[100] = "<grp?>";
 
+  ip_hdr = (const struct ip *) buf;
+
+  /* kernel upcall must have protocol=0 */
+  if (ip_hdr->ip_p) {
+    /* this is not a kernel upcall */
+    if (PIM_DEBUG_PIM_TRACE) {
+      zlog_debug("%s: not a kernel upcall proto=%d msg_size=%d",
+                __PRETTY_FUNCTION__, ip_hdr->ip_p, buf_size);
+    }
     return 0;
-  } /* IGMPMSG_WRONGVIF */
-
-  zlog_warn("%s: kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d",
-           __PRETTY_FUNCTION__,
-           upcall,
-           msg->im_msgtype,
-           ip_hdr->ip_p,
-           fd,
-           src_str,
-           grp_str,
-           ifp ? ifp->name : "<ifname?>",
-           msg->im_vif);
+  }
+
+  msg = (const struct igmpmsg *) buf;
+
+  ifp = pim_if_find_by_vif_index(msg->im_vif);
+
+  if (PIM_DEBUG_PIM_TRACE) {
+    pim_inet4_dump("<src?>", msg->im_src, src_str, sizeof(src_str));
+    pim_inet4_dump("<grp?>", msg->im_dst, grp_str, sizeof(grp_str));
+    zlog_warn("%s: kernel upcall %s type=%d ip_p=%d from fd=%d for (S,G)=(%s,%s) on %s vifi=%d",
+             __PRETTY_FUNCTION__,
+             igmpmsgtype2str[msg->im_msgtype],
+             msg->im_msgtype,
+             ip_hdr->ip_p,
+             fd,
+             src_str,
+             grp_str,
+             ifp ? ifp->name : "<ifname?>",
+             msg->im_vif);
+  }
+
+  switch (msg->im_msgtype) {
+  case IGMPMSG_WRONGVIF:
+    return pim_mroute_msg_wrongvif(fd, ifp, msg, src_str, grp_str);
+    break;
+  case IGMPMSG_NOCACHE:
+    return pim_mroute_msg_nocache(fd, ifp, msg, src_str, grp_str);
+    break;
+  case IGMPMSG_WHOLEPKT:
+    return pim_mroute_msg_wholepkt(fd, ifp, msg, src_str, grp_str);
+    break;
+  default:
+    break;
+  }
 
   return 0;
 }