]> git.puffer.fish Git - matthieu/frr.git/commitdiff
pimd: Fix various ifdown/ifup scenarios w/ J/P Agg
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 6 Mar 2017 17:56:32 +0000 (12:56 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 8 Mar 2017 13:37:53 +0000 (08:37 -0500)
There exists situations where we may have cleaned not
properly cleaned up the various J/P aggregation lists.
This commit fixes those issues.

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

index ca9d62e6336a63f745e7db0f72dcac0aa79fa324..3ffdbe2017b99bc6d6a7b3d16dc2690723662240 100644 (file)
@@ -81,15 +81,27 @@ pim_jp_agg_src_cmp (void *arg1, void *arg2)
   return 0;
 }
 
+/*
+ * This function is used by scan_oil to clear
+ * the created jp_agg_group created when
+ * figuring out where to send prunes
+ * and joins.
+ */
 void
 pim_jp_agg_clear_group (struct list *group)
 {
-  struct listnode *node, *nnode;
+  struct listnode *gnode, *gnnode;
+  struct listnode *snode, *snnode;
   struct pim_jp_agg_group *jag;
+  struct pim_jp_sources *js;
 
-  for (ALL_LIST_ELEMENTS(group, node, nnode, jag))
+  for (ALL_LIST_ELEMENTS(group, gnode, gnnode, jag))
     {
-      list_delete(jag->sources);
+      for (ALL_LIST_ELEMENTS(jag->sources, snode, snnode, js))
+        {
+          listnode_delete(jag->sources, js);
+          XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+        }
       jag->sources = NULL;
       listnode_delete(group, jag);
       XFREE(MTYPE_PIM_JP_AGG_GROUP, jag);
index ce567824f2e3e33c54bcfb3f4d277ef7b9a427b7..4187635b199c2cdedc1910d4cef498cd0ddf3e8d 100644 (file)
@@ -166,7 +166,6 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
   if (up->ref_count >= 1)
     return;
 
-  join_timer_stop(up);
   THREAD_OFF(up->t_ka_timer);
   THREAD_OFF(up->t_rs_timer);
   THREAD_OFF(up->t_msdp_reg_timer);
@@ -181,6 +180,9 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
     }
   }
 
+  join_timer_stop(up);
+  up->rpf.source_nexthop.interface = NULL;
+
   if (up->sg.src.s_addr != INADDR_ANY) {
     wheel_remove_item (pim_upstream_sg_wheel, up);
     notify_msdp = true;
@@ -252,7 +254,8 @@ static int on_join_timer(struct thread *t)
    * Don't send the join if the outgoing interface is a loopback
    * But since this might change leave the join timer running
    */
-  if (!if_is_loopback (up->rpf.source_nexthop.interface))
+  if (up->rpf.source_nexthop.interface &&
+      !if_is_loopback (up->rpf.source_nexthop.interface))
     pim_upstream_send_join (up);
 
   join_timer_start(up);
@@ -276,17 +279,20 @@ static void join_timer_stop(struct pim_upstream *up)
 void
 join_timer_start(struct pim_upstream *up)
 {
-  struct pim_neighbor *nbr;
-
-  nbr = pim_neighbor_find (up->rpf.source_nexthop.interface,
-                           up->rpf.rpf_addr.u.prefix4);
+  struct pim_neighbor *nbr = NULL;
 
-  if (PIM_DEBUG_PIM_EVENTS) {
-    zlog_debug("%s: starting %d sec timer for upstream (S,G)=%s",
-              __PRETTY_FUNCTION__,
-              qpim_t_periodic,
-              up->sg_str);
-  }
+  if (up->rpf.source_nexthop.interface)
+    {
+      nbr = pim_neighbor_find (up->rpf.source_nexthop.interface,
+                               up->rpf.rpf_addr.u.prefix4);
+
+      if (PIM_DEBUG_PIM_EVENTS) {
+        zlog_debug("%s: starting %d sec timer for upstream (S,G)=%s",
+                   __PRETTY_FUNCTION__,
+                   qpim_t_periodic,
+                   up->sg_str);
+      }
+    }
 
   if (nbr)
     pim_jp_agg_add_group (nbr->upstream_jp_agg, up, 1);