summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-03-16 12:56:59 -0400
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-03-16 18:59:44 -0400
commit06e12762c21bce1586f7dbea2cae05e8345d1b7b (patch)
tree29300d0a748020546667db21f8a619b64d492c8a
parentcb35003fdca20dfd12e260891acc8d0ceef5c03e (diff)
pimd: Add code to catch J/P Agg list issues
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r--pimd/pim_jp_agg.c69
-rw-r--r--pimd/pim_jp_agg.h3
-rw-r--r--pimd/pim_upstream.c3
3 files changed, 75 insertions, 0 deletions
diff --git a/pimd/pim_jp_agg.c b/pimd/pim_jp_agg.c
index 4c1c0c7de1..eb13ebf31b 100644
--- a/pimd/pim_jp_agg.c
+++ b/pimd/pim_jp_agg.c
@@ -22,6 +22,8 @@
#include "linklist.h"
#include "log.h"
+#include "vrf.h"
+#include "if.h"
#include "pimd.h"
#include "pim_msg.h"
@@ -181,6 +183,73 @@ pim_jp_agg_remove_group (struct list *group, struct pim_upstream *up)
}
}
+int
+pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up)
+{
+ struct listnode *node, *nnode;
+ struct pim_jp_agg_group *jag = NULL;
+ struct pim_jp_sources *js = NULL;
+
+ for (ALL_LIST_ELEMENTS (group, node, nnode, jag))
+ {
+ if (jag->group.s_addr == up->sg.grp.s_addr)
+ break;
+ }
+
+ if (!jag)
+ return 0;
+
+ for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
+ {
+ if (js->up == up)
+ return 1;
+ }
+
+ return 0;
+ }
+
+//#define PIM_JP_AGG_DEBUG 1
+/*
+ * For the given upstream, check all the neighbor
+ * jp_agg lists and ensure that it is not
+ * in another list
+ *
+ * *IF* ignore is true we can skip
+ * up->rpf.source_nexthop.interface particular interface for checking
+ *
+ * This is a debugging function, Probably
+ * can be safely compiled out in real
+ * builds
+ */
+void
+pim_jp_agg_upstream_verification (struct pim_upstream *up, bool ignore)
+{
+#ifdef PIM_JP_AGG_DEBUG
+ struct listnode *node;
+ struct interface *ifp;
+
+ for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp))
+ {
+ struct pim_interface *pim_ifp = ifp->info;
+ struct listnode *nnode;
+
+ if (ignore && ifp == up->rpf.source_nexthop.interface)
+ continue;
+
+ if (pim_ifp)
+ {
+ struct pim_neighbor *neigh;
+ for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_neighbor_list, nnode, neigh))
+ {
+ assert (!pim_jp_agg_is_in_list(neigh->upstream_jp_agg, up));
+ }
+ }
+ }
+#else
+ return;
+#endif
+}
+
void
pim_jp_agg_add_group (struct list *group, struct pim_upstream *up, bool is_join)
{
diff --git a/pimd/pim_jp_agg.h b/pimd/pim_jp_agg.h
index 4c84c120eb..b2cbdf6f41 100644
--- a/pimd/pim_jp_agg.h
+++ b/pimd/pim_jp_agg.h
@@ -34,6 +34,9 @@ struct pim_jp_agg_group
struct list *sources;
};
+void pim_jp_agg_upstream_verification (struct pim_upstream *up, bool ignore);
+int pim_jp_agg_is_in_list (struct list *group, struct pim_upstream *up);
+
void pim_jp_agg_group_list_free (struct pim_jp_agg_group *jag);
int pim_jp_agg_group_list_cmp (void *arg1, void *arg2);
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index 0f16bc0f86..31b623280b 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -187,6 +187,7 @@ pim_upstream_del(struct pim_upstream *up, const char *name)
}
join_timer_stop(up);
+ pim_jp_agg_upstream_verification (up, false);
up->rpf.source_nexthop.interface = NULL;
if (up->sg.src.s_addr != INADDR_ANY) {
@@ -297,6 +298,7 @@ static void join_timer_stop(struct pim_upstream *up)
pim_jp_agg_remove_group (nbr->upstream_jp_agg, up);
THREAD_OFF (up->t_join_timer);
+ pim_jp_agg_upstream_verification (up, false);
}
void
@@ -326,6 +328,7 @@ join_timer_start(struct pim_upstream *up)
on_join_timer,
up, qpim_t_periodic);
}
+ pim_jp_agg_upstream_verification (up, true);
}
/*