]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_upstream.c
lib: enforce vrf_name_to_id by returning default_vrf when name is null
[mirror_frr.git] / pimd / pim_upstream.c
index b5f5f646d42aba7aebe4a61d71d9b848403bbb42..cd5b632dedb95d006a1f86d63afee0331831d614 100644 (file)
@@ -19,8 +19,6 @@
 
 #include <zebra.h>
 
-#include "zebra/rib.h"
-
 #include "log.h"
 #include "zclient.h"
 #include "memory.h"
@@ -82,7 +80,7 @@ static void pim_upstream_remove_children(struct pim_instance *pim,
                if (child)
                        child->parent = NULL;
        }
-       list_delete_and_null(&up->sources);
+       list_delete(&up->sources);
 }
 
 /*
@@ -140,12 +138,6 @@ static struct pim_upstream *pim_upstream_find_parent(struct pim_instance *pim,
        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) {
@@ -161,6 +153,8 @@ static void upstream_channel_oil_detach(struct pim_upstream *up)
 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;
 
@@ -171,6 +165,8 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
                        up->ref_count, up->flags,
                        up->channel_oil->oil_ref_count);
 
+        assert(up->ref_count > 0);
+
        --up->ref_count;
 
        if (up->ref_count >= 1)
@@ -196,24 +192,22 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
        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;
@@ -237,7 +231,7 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
        }
        pim_delete_tracked_nexthop(pim, &nht_p, up, NULL);
 
-       pim_upstream_free(up);
+       XFREE(MTYPE_PIM_UPSTREAM, up);
 
        return NULL;
 }
@@ -468,7 +462,7 @@ static int pim_upstream_could_register(struct pim_upstream *up)
        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)
 {
@@ -610,11 +604,6 @@ static struct pim_upstream *pim_upstream_new(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);
@@ -694,9 +683,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
 
                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);
@@ -1545,24 +1534,36 @@ unsigned int pim_upstream_hash_key(void *arg)
 
 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
@@ -1762,17 +1763,19 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
 
 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;
 }