]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Convert to using a RB tree for the pim_ifp ifchannel_list
authorDonald Sharp <sharpd@cumulusnetworks.com>
Mon, 31 Jul 2017 16:44:20 +0000 (12:44 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 2 Aug 2017 11:44:00 +0000 (07:44 -0400)
This patch does two things:
1) Converts the pim_ifp->ifchannel_list to a pim_ifp->ifchannel_rb
2) Removes the hashing to use the RB RB_FIND instead.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_iface.h
pimd/pim_ifchannel.c
pimd/pim_ifchannel.h

index 6dfd9c2d6085f27c984e7e7b7efcfa294242a062..0cc8f0c87ed9509d2fd206f33116180b3bbd6c69 100644 (file)
@@ -213,7 +213,6 @@ static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
 {
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
-       struct listnode *ch_node;
        struct listnode *if_node;
        struct interface *ifp;
        time_t now;
@@ -228,8 +227,7 @@ static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        pim_show_assert_helper(vty, pim_ifp, ch, now);
                } /* scan interface channels */
        }
@@ -264,7 +262,6 @@ static void pim_show_assert_internal_helper(struct vty *vty,
 static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *ch_node;
        struct listnode *if_node;
        struct pim_ifchannel *ch;
        struct interface *ifp;
@@ -282,8 +279,7 @@ static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        pim_show_assert_internal_helper(vty, pim_ifp, ch);
                } /* scan interface channels */
        }
@@ -320,7 +316,7 @@ static void pim_show_assert_metric_helper(struct vty *vty,
 static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *ch_node, *if_node;
+       struct listnode *if_node;
        struct pim_ifchannel *ch;
        struct interface *ifp;
 
@@ -332,8 +328,7 @@ static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        pim_show_assert_metric_helper(vty, pim_ifp, ch);
                } /* scan interface channels */
        }
@@ -383,7 +378,7 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty,
 static void pim_show_assert_winner_metric(struct pim_instance *pim,
                                          struct vty *vty)
 {
-       struct listnode *ch_node, *if_node;
+       struct listnode *if_node;
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
        struct interface *ifp;
@@ -396,8 +391,7 @@ static void pim_show_assert_winner_metric(struct pim_instance *pim,
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
                } /* scan interface channels */
        }
@@ -472,7 +466,7 @@ static void pim_show_membership_helper(struct vty *vty,
 static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
                                u_char uj)
 {
-       struct listnode *ch_node, *if_node;
+       struct listnode *if_node;
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
        struct interface *ifp;
@@ -487,8 +481,7 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        pim_show_membership_helper(vty, pim_ifp, ch, json);
                } /* scan interface channels */
        }
@@ -1364,7 +1357,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
                        continue;
 
                pim_nbrs = pim_ifp->pim_neighbor_list->count;
-               pim_ifchannels = pim_ifp->ifchannel_list->count;
+               pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
                fhr = 0;
 
                for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
@@ -1684,7 +1677,7 @@ static void pim_show_join_helper(struct vty *vty,
 
 static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj)
 {
-       struct listnode *ch_node, *if_node;
+       struct listnode *if_node;
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
        struct interface *ifp;
@@ -1704,8 +1697,7 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj)
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        pim_show_join_helper(vty, pim_ifp,
                                             ch, json, now, uj);
                } /* scan interface channels */
@@ -2515,7 +2507,7 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
 static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
                                  u_char uj)
 {
-       struct listnode *ch_node, *if_node;
+       struct listnode *if_node;
        struct pim_interface *pim_ifp;
        struct pim_ifchannel *ch;
        struct interface *ifp;
@@ -2534,8 +2526,8 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
                if (!pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+
+               RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                        /* scan all interfaces */
                        pim_show_join_desired_helper(pim, vty,
                                                     pim_ifp, ch,
index 2fabf37a5e0170cb9f815e36855b2510493238f5..221ca2f24d118ba819765942ce59f66da88fcddf 100644 (file)
@@ -66,6 +66,8 @@ void pim_if_terminate(struct pim_instance *pim)
 
 static void *if_list_clean(struct pim_interface *pim_ifp)
 {
+       struct pim_ifchannel *ch;
+
        if (pim_ifp->igmp_join_list) {
                list_delete(pim_ifp->igmp_join_list);
        }
@@ -81,11 +83,9 @@ static void *if_list_clean(struct pim_interface *pim_ifp)
        if (pim_ifp->upstream_switch_list)
                list_delete(pim_ifp->upstream_switch_list);
 
-       if (pim_ifp->ifchannel_list)
-               list_delete(pim_ifp->ifchannel_list);
-
-       if (pim_ifp->pim_ifchannel_hash)
-               hash_free(pim_ifp->pim_ifchannel_hash);
+       while ((ch = RB_ROOT(pim_ifchannel_rb,
+                            &pim_ifp->ifchannel_rb)) != NULL)
+               pim_ifchannel_delete(ch);
 
        XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
 
@@ -95,7 +95,6 @@ static void *if_list_clean(struct pim_interface *pim_ifp)
 struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
 {
        struct pim_interface *pim_ifp;
-       char hash_name[64];
 
        zassert(ifp);
        zassert(!ifp->info);
@@ -138,8 +137,6 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
        pim_ifp->igmp_socket_list = NULL;
        pim_ifp->pim_neighbor_list = NULL;
        pim_ifp->upstream_switch_list = NULL;
-       pim_ifp->ifchannel_list = NULL;
-       pim_ifp->pim_ifchannel_hash = NULL;
        pim_ifp->pim_generation_id = 0;
 
        /* list of struct igmp_sock */
@@ -167,22 +164,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
                return if_list_clean(pim_ifp);
        }
 
-       /* list of struct pim_ifchannel */
-       pim_ifp->ifchannel_list = list_new();
-       if (!pim_ifp->ifchannel_list) {
-               zlog_err("%s %s: failure: pim_ifchannel_list=list_new()",
-                        __FILE__, __PRETTY_FUNCTION__);
-               return if_list_clean(pim_ifp);
-       }
-       pim_ifp->ifchannel_list->del = (void (*)(void *))pim_ifchannel_free;
-       pim_ifp->ifchannel_list->cmp =
-               (int (*)(void *, void *))pim_ifchannel_compare;
-
-       snprintf(hash_name, 64, "Pim Interface %s hash",
-                ifp->name);
-       pim_ifp->pim_ifchannel_hash =
-               hash_create(pim_ifchannel_hash_key, pim_ifchannel_equal,
-                           hash_name);
+       RB_INIT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb);
 
        ifp->info = pim_ifp;
 
@@ -196,6 +178,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
 void pim_if_delete(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
+       struct pim_ifchannel *ch;
 
        zassert(ifp);
        pim_ifp = ifp->info;
@@ -215,9 +198,10 @@ void pim_if_delete(struct interface *ifp)
        list_delete(pim_ifp->igmp_socket_list);
        list_delete(pim_ifp->pim_neighbor_list);
        list_delete(pim_ifp->upstream_switch_list);
-       list_delete(pim_ifp->ifchannel_list);
 
-       hash_free(pim_ifp->pim_ifchannel_hash);
+       while ((ch = RB_ROOT(pim_ifchannel_rb,
+                            &pim_ifp->ifchannel_rb)) != NULL)
+               pim_ifchannel_delete(ch);
 
        XFREE(MTYPE_PIM_INTERFACE, pim_ifp);
 
@@ -227,15 +211,12 @@ void pim_if_delete(struct interface *ifp)
 void pim_if_update_could_assert(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *node;
-       struct listnode *next_node;
        struct pim_ifchannel *ch;
 
        pim_ifp = ifp->info;
        zassert(pim_ifp);
 
-       for (ALL_LIST_ELEMENTS(pim_ifp->ifchannel_list, node, next_node,
-                              ch)) {
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                pim_ifchannel_update_could_assert(ch);
        }
 }
@@ -243,15 +224,12 @@ void pim_if_update_could_assert(struct interface *ifp)
 static void pim_if_update_my_assert_metric(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *node;
-       struct listnode *next_node;
        struct pim_ifchannel *ch;
 
        pim_ifp = ifp->info;
        zassert(pim_ifp);
 
-       for (ALL_LIST_ELEMENTS(pim_ifp->ifchannel_list, node, next_node,
-                              ch)) {
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                pim_ifchannel_update_my_assert_metric(ch);
        }
 }
@@ -1472,15 +1450,12 @@ void pim_if_assert_on_neighbor_down(struct interface *ifp,
                                    struct in_addr neigh_addr)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *node;
-       struct listnode *next_node;
        struct pim_ifchannel *ch;
 
        pim_ifp = ifp->info;
        zassert(pim_ifp);
 
-       for (ALL_LIST_ELEMENTS(pim_ifp->ifchannel_list, node, next_node,
-                              ch)) {
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                /* Is (S,G,I) assert loser ? */
                if (ch->ifassert_state != PIM_IFASSERT_I_AM_LOSER)
                        continue;
@@ -1494,17 +1469,16 @@ void pim_if_assert_on_neighbor_down(struct interface *ifp,
 
 void pim_if_update_join_desired(struct pim_interface *pim_ifp)
 {
-       struct listnode *ch_node;
        struct pim_ifchannel *ch;
 
        /* clear off flag from interface's upstreams */
-       for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list, ch_node, ch)) {
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                PIM_UPSTREAM_FLAG_UNSET_DR_JOIN_DESIRED_UPDATED(
                        ch->upstream->flags);
        }
 
        /* scan per-interface (S,G,I) state on this I interface */
-       for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list, ch_node, ch)) {
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                struct pim_upstream *up = ch->upstream;
 
                if (PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED_UPDATED(up->flags))
@@ -1519,16 +1493,13 @@ void pim_if_update_join_desired(struct pim_interface *pim_ifp)
 void pim_if_update_assert_tracking_desired(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *node;
-       struct listnode *next_node;
        struct pim_ifchannel *ch;
 
        pim_ifp = ifp->info;
        if (!pim_ifp)
                return;
 
-       for (ALL_LIST_ELEMENTS(pim_ifp->ifchannel_list, node, next_node,
-                              ch)) {
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                pim_ifchannel_update_assert_tracking_desired(ch);
        }
 }
@@ -1603,3 +1574,15 @@ int pim_if_is_vrf_device(struct interface *ifp)
 
        return 0;
 }
+
+int pim_if_ifchannel_count(struct pim_interface *pim_ifp)
+{
+       struct pim_ifchannel *ch;
+       int count = 0;
+
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
+               count++;
+       }
+
+       return count;
+}
index 7739e3af2b11592da43d9d423745e91025446372..ed885ff0e375c6f282fceca3bff82c5304719ba2 100644 (file)
@@ -106,8 +106,7 @@ struct pim_interface {
        uint16_t pim_override_interval_msec; /* config */
        struct list *pim_neighbor_list;      /* list of struct pim_neighbor */
        struct list *upstream_switch_list;
-       struct list *ifchannel_list;
-       struct hash *pim_ifchannel_hash;
+       struct pim_ifchannel_rb ifchannel_rb;
 
        /* neighbors without lan_delay */
        int pim_number_of_nonlandelay_neighbors;
@@ -208,4 +207,6 @@ int pim_update_source_set(struct interface *ifp, struct in_addr source);
 int pim_if_is_loopback(struct pim_instance *pim, struct interface *ifp);
 
 int pim_if_is_vrf_device(struct interface *ifp);
+
+int pim_if_ifchannel_count(struct pim_interface *pim_ifp);
 #endif /* PIM_IFACE_H */
index 750dc7f5e961e14a185211f8c1c52cdb6c09b0ab..c91efbd8b624e3e685df440262b2d3b85d8e7fe8 100644 (file)
 #include "pim_upstream.h"
 #include "pim_ssm.h"
 
-int pim_ifchannel_compare(struct pim_ifchannel *ch1, struct pim_ifchannel *ch2)
+RB_GENERATE(pim_ifchannel_rb, pim_ifchannel,
+           pim_ifp_rb, pim_ifchannel_compare);
+
+int pim_ifchannel_compare(const struct pim_ifchannel *ch1,
+                         const struct pim_ifchannel *ch2)
 {
        struct pim_interface *pim_ifp1;
        struct pim_interface *pim_ifp2;
@@ -100,7 +104,6 @@ static void pim_ifchannel_find_new_children(struct pim_ifchannel *ch)
 {
        struct pim_interface *pim_ifp = ch->interface->info;
        struct pim_ifchannel *child;
-       struct listnode *ch_node;
 
        // Basic Sanity that we are not being silly
        if ((ch->sg.src.s_addr != INADDR_ANY)
@@ -111,8 +114,7 @@ static void pim_ifchannel_find_new_children(struct pim_ifchannel *ch)
            && (ch->sg.grp.s_addr == INADDR_ANY))
                return;
 
-       for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list, ch_node,
-                                 child)) {
+       RB_FOREACH(child, pim_ifchannel_rb, &pim_ifp->ifchannel_rb) {
                if ((ch->sg.grp.s_addr != INADDR_ANY)
                    && (child->sg.grp.s_addr == ch->sg.grp.s_addr)
                    && (child != ch)) {
@@ -189,13 +191,8 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
                listnode_delete(ch->parent->sources, ch);
                ch->parent = NULL;
        }
-       /*
-         notice that listnode_delete() can't be moved
-         into pim_ifchannel_free() because the later is
-         called by list_delete_all_node()
-       */
-       listnode_delete(pim_ifp->ifchannel_list, ch);
-       hash_release(pim_ifp->pim_ifchannel_hash, ch);
+
+       RB_REMOVE(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch);
 
        if (PIM_DEBUG_PIM_TRACE)
                zlog_debug("%s: ifchannel entry %s is deleted ",
@@ -207,17 +204,15 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
 void pim_ifchannel_delete_all(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *ifchannel_node;
-       struct listnode *ifchannel_nextnode;
-       struct pim_ifchannel *ifchannel;
+       struct pim_ifchannel *ch;
 
        pim_ifp = ifp->info;
        if (!pim_ifp)
                return;
 
-       for (ALL_LIST_ELEMENTS(pim_ifp->ifchannel_list, ifchannel_node,
-                              ifchannel_nextnode, ifchannel)) {
-               pim_ifchannel_delete(ifchannel);
+       while ((ch = RB_ROOT(pim_ifchannel_rb,
+                            &pim_ifp->ifchannel_rb)) != NULL) {
+               pim_ifchannel_delete(ch);
        }
 }
 
@@ -423,7 +418,8 @@ struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,
        }
 
        lookup.sg = *sg;
-       ch = hash_lookup(pim_ifp->pim_ifchannel_hash, &lookup);
+       lookup.interface = ifp;
+       ch = RB_FIND(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, &lookup);
 
        return ch;
 }
@@ -455,30 +451,25 @@ static void ifmembership_set(struct pim_ifchannel *ch,
 void pim_ifchannel_membership_clear(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *ch_node;
        struct pim_ifchannel *ch;
 
        pim_ifp = ifp->info;
        zassert(pim_ifp);
 
-       for (ALL_LIST_ELEMENTS_RO(pim_ifp->ifchannel_list, ch_node, ch))
+       RB_FOREACH(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb)
                ifmembership_set(ch, PIM_IFMEMBERSHIP_NOINFO);
 }
 
 void pim_ifchannel_delete_on_noinfo(struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
-       struct listnode *node;
-       struct listnode *next_node;
-       struct pim_ifchannel *ch;
+       struct pim_ifchannel *ch, *ch_tmp;
 
        pim_ifp = ifp->info;
        zassert(pim_ifp);
 
-       for (ALL_LIST_ELEMENTS(pim_ifp->ifchannel_list, node, next_node,
-                              ch)) {
+       RB_FOREACH_SAFE(ch, pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch_tmp)
                delete_on_noinfo(ch);
-       }
 }
 
 /*
@@ -552,9 +543,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
        ch->t_ifjoin_prune_pending_timer = NULL;
        ch->ifjoin_creation = 0;
 
-       /* Attach to list */
-       listnode_add_sort(pim_ifp->ifchannel_list, ch);
-       ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern);
+       RB_INSERT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch);
 
        up = pim_upstream_add(pim_ifp->pim, sg, NULL, up_flags,
                              __PRETTY_FUNCTION__, ch);
@@ -572,8 +561,7 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
                THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
                THREAD_OFF(ch->t_ifassert_timer);
 
-               listnode_delete(pim_ifp->ifchannel_list, ch);
-               hash_release(pim_ifp->pim_ifchannel_hash, ch);
+               RB_REMOVE(pim_ifchannel_rb, &pim_ifp->ifchannel_rb, ch);
                XFREE(MTYPE_PIM_IFCHANNEL, ch);
                return NULL;
        }
@@ -1285,14 +1273,13 @@ void pim_ifchannel_update_assert_tracking_desired(struct pim_ifchannel *ch)
  */
 void pim_ifchannel_scan_forward_start(struct interface *new_ifp)
 {
-       struct listnode *ifnode;
-       struct interface *ifp;
        struct pim_interface *new_pim_ifp = new_ifp->info;
        struct pim_instance *pim = new_pim_ifp->pim;
+       struct listnode *ifnode;
+       struct interface *ifp;
 
        for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), ifnode, ifp)) {
                struct pim_interface *loop_pim_ifp = ifp->info;
-               struct listnode *ch_node;
                struct pim_ifchannel *ch;
 
                if (!loop_pim_ifp)
@@ -1301,8 +1288,7 @@ void pim_ifchannel_scan_forward_start(struct interface *new_ifp)
                if (new_pim_ifp == loop_pim_ifp)
                        continue;
 
-               for (ALL_LIST_ELEMENTS_RO(loop_pim_ifp->ifchannel_list,
-                                         ch_node, ch)) {
+               RB_FOREACH(ch, pim_ifchannel_rb, &loop_pim_ifp->ifchannel_rb) {
                        if (ch->ifjoin_state == PIM_IFJOIN_JOIN) {
                                struct pim_upstream *up = ch->upstream;
                                if ((!up->channel_oil)
@@ -1395,15 +1381,3 @@ unsigned int pim_ifchannel_hash_key(void *arg)
 
        return jhash_2words(ch->sg.src.s_addr, ch->sg.grp.s_addr, 0);
 }
-
-int pim_ifchannel_equal(const void *arg1, const void *arg2)
-{
-       const struct pim_ifchannel *ch1 = (const struct pim_ifchannel *)arg1;
-       const struct pim_ifchannel *ch2 = (const struct pim_ifchannel *)arg2;
-
-       if ((ch1->sg.grp.s_addr == ch2->sg.grp.s_addr)
-           && (ch1->sg.src.s_addr == ch2->sg.src.s_addr))
-               return 1;
-
-       return 0;
-}
index 3fd717bec8d4c15a05d1a3f69d8e047b21126b57..cef431c30d0f35af712b968a83998b26d853bd2f 100644 (file)
@@ -80,6 +80,8 @@ struct pim_assert_metric {
   Per-interface (S,G) state
 */
 struct pim_ifchannel {
+       RB_ENTRY(rb_ifchannel) pim_ifp_rb;
+
        struct pim_ifchannel *parent;
        struct list *sources;
        struct prefix_sg sg;
@@ -108,6 +110,10 @@ struct pim_ifchannel {
        struct pim_upstream *upstream;
 };
 
+RB_HEAD(pim_ifchannel_rb, pim_ifchannel);
+RB_PROTOTYPE(pim_ifchannel_rb, pim_ifchannel,
+            pim_ifp_rb, pim_ifchannel_compare);
+
 void pim_ifchannel_free(struct pim_ifchannel *ch);
 void pim_ifchannel_delete(struct pim_ifchannel *ch);
 void pim_ifchannel_delete_all(struct interface *ifp);
@@ -148,8 +154,8 @@ void pim_ifchannel_set_star_g_join_state(struct pim_ifchannel *ch, int eom,
                                         uint8_t source_flags, uint8_t join,
                                         uint8_t starg_alone);
 
-int pim_ifchannel_compare(struct pim_ifchannel *ch1, struct pim_ifchannel *ch2);
+int pim_ifchannel_compare(const struct pim_ifchannel *ch1,
+                         const struct pim_ifchannel *ch2);
 
 unsigned int pim_ifchannel_hash_key(void *arg);
-int pim_ifchannel_equal(const void *arg1, const void *arg2);
 #endif /* PIM_IFCHANNEL_H */