#include <zebra.h>
-#include "zebra/rib.h"
-
#include "log.h"
#include "zclient.h"
#include "memory.h"
if (child)
child->parent = NULL;
}
- list_delete_and_null(&up->sources);
+ list_delete(&up->sources);
}
/*
return NULL;
}
-void pim_upstream_free(struct pim_upstream *up)
-{
- XFREE(MTYPE_PIM_UPSTREAM, up);
- up = NULL;
-}
-
static void upstream_channel_oil_detach(struct pim_upstream *up)
{
if (up->channel_oil) {
struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
struct pim_upstream *up, const char *name)
{
+ struct listnode *node, *nnode;
+ struct pim_ifchannel *ch;
bool notify_msdp = false;
struct prefix nht_p;
up->ref_count, up->flags,
up->channel_oil->oil_ref_count);
+ assert(up->ref_count > 0);
+
--up->ref_count;
if (up->ref_count >= 1)
up->rpf.source_nexthop.interface = NULL;
if (up->sg.src.s_addr != INADDR_ANY) {
- wheel_remove_item(pim->upstream_sg_wheel, up);
+ if (pim->upstream_sg_wheel)
+ wheel_remove_item(pim->upstream_sg_wheel, up);
notify_msdp = true;
}
- pim_upstream_remove_children(pim, up);
- if (up->sources)
- list_delete_and_null(&up->sources);
-
pim_mroute_del(up->channel_oil, __PRETTY_FUNCTION__);
upstream_channel_oil_detach(up);
- list_delete_and_null(&up->ifchannels);
+ for (ALL_LIST_ELEMENTS(up->ifchannels, node, nnode, ch))
+ pim_ifchannel_delete(ch);
+ list_delete(&up->ifchannels);
+
+ pim_upstream_remove_children(pim, up);
+ if (up->sources)
+ list_delete(&up->sources);
- /*
- notice that listnode_delete() can't be moved
- into pim_upstream_free() because the later is
- called by list_delete_all_node()
- */
if (up->parent && up->parent->sources)
listnode_delete(up->parent->sources, up);
up->parent = NULL;
}
pim_delete_tracked_nexthop(pim, &nht_p, up, NULL);
- pim_upstream_free(up);
+ XFREE(MTYPE_PIM_UPSTREAM, up);
return NULL;
}
return 0;
}
-/* Source registration is supressed for SSM groups. When the SSM range changes
+/* Source registration is suppressed for SSM groups. When the SSM range changes
* we re-revaluate register setup for existing upstream entries */
void pim_upstream_register_reevaluate(struct pim_instance *pim)
{
struct pim_upstream *up;
up = XCALLOC(MTYPE_PIM_UPSTREAM, sizeof(*up));
- if (!up) {
- zlog_err("%s: PIM XCALLOC(%zu) failure", __PRETTY_FUNCTION__,
- sizeof(*up));
- return NULL;
- }
up->sg = *sg;
pim_str_sg_set(sg, up->sg_str);
pim_upstream_remove_children(pim, up);
if (up->sources)
- list_delete_and_null(&up->sources);
+ list_delete(&up->sources);
- list_delete_and_null(&up->ifchannels);
+ list_delete(&up->ifchannels);
hash_release(pim->upstream_hash, up);
XFREE(MTYPE_PIM_UPSTREAM, up);
void pim_upstream_terminate(struct pim_instance *pim)
{
- if (pim->upstream_list)
- list_delete_and_null(&pim->upstream_list);
+ struct pim_upstream *up;
+
+ if (pim->upstream_list) {
+ while (pim->upstream_list->count) {
+ up = listnode_head(pim->upstream_list);
+ pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
+ }
+
+ list_delete(&pim->upstream_list);
+ }
if (pim->upstream_hash)
hash_free(pim->upstream_hash);
pim->upstream_hash = NULL;
+
+ if (pim->upstream_sg_wheel)
+ wheel_delete(pim->upstream_sg_wheel);
+ pim->upstream_sg_wheel = NULL;
}
-int pim_upstream_equal(const void *arg1, const void *arg2)
+bool pim_upstream_equal(const void *arg1, const void *arg2)
{
const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
if ((up1->sg.grp.s_addr == up2->sg.grp.s_addr)
&& (up1->sg.src.s_addr == up2->sg.src.s_addr))
- return 1;
+ return true;
- return 0;
+ return false;
}
/* rfc4601:section-4.2:"Data Packet Forwarding Rules" defines
void pim_upstream_init(struct pim_instance *pim)
{
- char hash_name[64];
+ char name[64];
+ snprintf(name, 64, "PIM %s Timer Wheel",
+ pim->vrf->name);
pim->upstream_sg_wheel =
wheel_init(master, 31000, 100, pim_upstream_hash_key,
- pim_upstream_sg_running);
+ pim_upstream_sg_running, name);
- snprintf(hash_name, 64, "PIM %s Upstream Hash", pim->vrf->name);
+ snprintf(name, 64, "PIM %s Upstream Hash",
+ pim->vrf->name);
pim->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
- pim_upstream_equal, hash_name);
+ pim_upstream_equal, name);
pim->upstream_list = list_new();
- pim->upstream_list->del = (void (*)(void *))pim_upstream_free;
pim->upstream_list->cmp = pim_upstream_compare;
}