static void
pim_jp_agg_src_free (struct pim_jp_sources *js)
{
+ struct pim_upstream *up = js->up;
+
/*
* When we are being called here, we know
* that the neighbor is going away start
* pick this shit back up when the
* nbr comes back alive
*/
- join_timer_start(js->up);
+
+ up = pim_upstream_del (up, __PRETTY_FUNCTION__);
+
+ if (up)
+ join_timer_start(js->up);
XFREE (MTYPE_PIM_JP_AGG_SOURCE, js);
}
const struct pim_jp_sources *js1 = (const struct pim_jp_sources *)arg1;
const struct pim_jp_sources *js2 = (const struct pim_jp_sources *)arg2;
+ if (js1->is_join && !js2->is_join)
+ return -1;
+
+ if (!js1->is_join && js2->is_join)
+ return 1;
+
if (js1->up->sg.src.s_addr < js2->up->sg.src.s_addr)
return -1;
{
for (ALL_LIST_ELEMENTS(jag->sources, snode, snnode, js))
{
+ pim_upstream_del (js->up, __PRETTY_FUNCTION__);
listnode_delete(jag->sources, js);
XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
}
pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP, sizeof (struct pim_iface_upstream_switch));
pius->address.s_addr = rpf->rpf_addr.u.prefix4.s_addr;
pius->us = list_new();
- listnode_add (pim_ifp->upstream_switch_list, pius);
+ listnode_add_sort (pim_ifp->upstream_switch_list, pius);
}
return pius;
break;
}
- listnode_delete(jag->sources, js);
-
- XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+ if (js)
+ {
+ pim_upstream_del (up, __PRETTY_FUNCTION__);
+ listnode_delete(jag->sources, js);
+ XFREE(MTYPE_PIM_JP_AGG_SOURCE, js);
+ }
if (jag->sources->count == 0)
{
jag->sources = list_new();
jag->sources->cmp = pim_jp_agg_src_cmp;
jag->sources->del = (void (*)(void *))pim_jp_agg_src_free;
- listnode_add (group, jag);
+ listnode_add_sort (group, jag);
}
for (ALL_LIST_ELEMENTS(jag->sources, node, nnode, js))
if (!js)
{
js = XCALLOC(MTYPE_PIM_JP_AGG_SOURCE, sizeof (struct pim_jp_sources));
+ pim_upstream_ref (up, 0);
js->up = up;
- listnode_add (jag->sources, js);
+ js->is_join = is_join;
+ listnode_add_sort (jag->sources, js);
+ }
+ else
+ {
+ if (js->is_join != is_join)
+ {
+ listnode_delete(jag->sources, js);
+ js->is_join = is_join;
+ listnode_add_sort (jag->sources, js);
+ }
}
-
- js->is_join = is_join;
}
void
void pim_upstream_free(struct pim_upstream *up)
{
+ memset (up, 0, sizeof (struct pim_upstream));
XFREE(MTYPE_PIM_UPSTREAM, up);
up = NULL;
}
}
}
-void
+struct pim_upstream *
pim_upstream_del(struct pim_upstream *up, const char *name)
{
bool notify_msdp = false;
--up->ref_count;
if (up->ref_count >= 1)
- return;
+ return up;
+ else if (up->ref_count < 0)
+ return NULL;
THREAD_OFF(up->t_ka_timer);
THREAD_OFF(up->t_rs_timer);
pim_delete_tracked_nexthop (&nht_p, up, NULL);
pim_upstream_free (up);
+
+ return NULL;
}
void
return up;
}
-static void pim_upstream_ref(struct pim_upstream *up, int flags)
+void
+pim_upstream_ref(struct pim_upstream *up, int flags)
{
up->flags |= flags;
++up->ref_count;
struct pim_upstream *pim_upstream_add (struct prefix_sg *sg,
struct interface *ifp, int flags,
const char *name);
-void pim_upstream_del(struct pim_upstream *up, const char *name);
+void pim_upstream_ref (struct pim_upstream *up, int flags);
+struct pim_upstream *pim_upstream_del(struct pim_upstream *up, const char *name);
int pim_upstream_evaluate_join_desired(struct pim_upstream *up);
int pim_upstream_evaluate_join_desired_interface(struct pim_upstream *up,