diff options
-rw-r--r-- | pimd/pim_cmd.c | 11 | ||||
-rw-r--r-- | pimd/pim_instance.h | 4 | ||||
-rw-r--r-- | pimd/pim_oil.c | 33 | ||||
-rw-r--r-- | pimd/pim_oil.h | 9 | ||||
-rw-r--r-- | pimd/pim_zebra.c | 5 |
5 files changed, 28 insertions, 34 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index d165cca08..4f5ad89f8 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1975,7 +1975,6 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty, const char *src_or_group, const char *group, bool uj) { struct channel_oil *c_oil; - struct listnode *node; json_object *json = NULL; json_object *json_group = NULL; json_object *json_ifp_in = NULL; @@ -1994,7 +1993,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty, "\nActive Source Group RPT IIF OIL\n"); } - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { char grp_str[INET_ADDRSTRLEN]; char src_str[INET_ADDRSTRLEN]; char in_ifname[INTERFACE_NAMSIZ + 1]; @@ -5420,7 +5419,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty, now = pim_time_monotonic_sec(); /* print list of PIM and IGMP routes */ - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { found_oif = 0; first = 1; if (!c_oil->installed && !uj) @@ -5828,7 +5827,7 @@ DEFUN (clear_ip_mroute_count, return CMD_WARNING; pim = vrf->info; - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { + frr_each(rb_pim_oil, &pim->channel_oil_head, c_oil) { if (!c_oil->installed) continue; @@ -5863,7 +5862,7 @@ static void show_mroute_count(struct pim_instance *pim, struct vty *vty) "Source Group LastUsed Packets Bytes WrongIf \n"); /* Print PIM and IGMP route counts */ - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { char group_str[INET_ADDRSTRLEN]; char source_str[INET_ADDRSTRLEN]; @@ -5968,7 +5967,7 @@ static void show_mroute_summary(struct pim_instance *pim, struct vty *vty) vty_out(vty, "Mroute Type Installed/Total\n"); - for (ALL_LIST_ELEMENTS_RO(pim->channel_oil_list, node, c_oil)) { + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) { if (!c_oil->installed) { if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) starg_sw_mroute_cnt++; diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index dd3ac8fcb..5a95043df 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -28,6 +28,7 @@ #include "pim_assert.h" #include "pim_bsm.h" #include "pim_vxlan_instance.h" +#include "pim_oil.h" #if defined(HAVE_LINUX_MROUTE_H) #include <linux/mroute.h> @@ -119,8 +120,7 @@ struct pim_instance { int iface_vif_index[MAXVIFS]; - struct list *channel_oil_list; - struct hash *channel_oil_hash; + struct rb_pim_oil_head channel_oil_head; struct pim_msdp msdp; struct pim_vxlan_instance vxlan; diff --git a/pimd/pim_oil.c b/pimd/pim_oil.c index 65c6bdd2b..5af3328a1 100644 --- a/pimd/pim_oil.c +++ b/pimd/pim_oil.c @@ -64,8 +64,8 @@ char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size) return buf; } -static int pim_channel_oil_compare(struct channel_oil *c1, - struct channel_oil *c2) +int pim_channel_oil_compare(const struct channel_oil *c1, + const struct channel_oil *c2) { if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) < ntohl(c2->oil.mfcc_mcastgrp.s_addr)) @@ -108,26 +108,17 @@ static unsigned int pim_oil_hash_key(const void *arg) void pim_oil_init(struct pim_instance *pim) { - char hash_name[64]; - - snprintf(hash_name, 64, "PIM %s Oil Hash", pim->vrf->name); - pim->channel_oil_hash = hash_create_size(8192, pim_oil_hash_key, - pim_oil_equal, hash_name); - - pim->channel_oil_list = list_new(); - pim->channel_oil_list->del = (void (*)(void *))pim_channel_oil_free; - pim->channel_oil_list->cmp = - (int (*)(void *, void *))pim_channel_oil_compare; + rb_pim_oil_init(&pim->channel_oil_head); } void pim_oil_terminate(struct pim_instance *pim) { - if (pim->channel_oil_list) - list_delete(&pim->channel_oil_list); + struct channel_oil *c_oil; + + while ((c_oil = rb_pim_oil_pop(&pim->channel_oil_head))) + pim_channel_oil_free(c_oil); - if (pim->channel_oil_hash) - hash_free(pim->channel_oil_hash); - pim->channel_oil_hash = NULL; + rb_pim_oil_fini(&pim->channel_oil_head); } void pim_channel_oil_free(struct channel_oil *c_oil) @@ -144,7 +135,7 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim, lookup.oil.mfcc_mcastgrp = sg->grp; lookup.oil.mfcc_origin = sg->src; - c_oil = hash_lookup(pim->channel_oil_hash, &lookup); + c_oil = rb_pim_oil_find(&pim->channel_oil_head, &lookup); return c_oil; } @@ -187,7 +178,6 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, c_oil->oil.mfcc_mcastgrp = sg->grp; c_oil->oil.mfcc_origin = sg->src; - c_oil = hash_get(pim->channel_oil_hash, c_oil, hash_alloc_intern); c_oil->oil.mfcc_parent = MAXVIFS; c_oil->oil_ref_count = 1; @@ -195,7 +185,7 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim, c_oil->up = pim_upstream_find(pim, sg); c_oil->pim = pim; - listnode_add_sort(pim->channel_oil_list, c_oil); + rb_pim_oil_add(&pim->channel_oil_head, c_oil); if (PIM_DEBUG_MROUTE) zlog_debug("%s(%s): c_oil %s add", @@ -224,8 +214,7 @@ struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil, * called by list_delete_all_node() */ c_oil->up = NULL; - listnode_delete(c_oil->pim->channel_oil_list, c_oil); - hash_release(c_oil->pim->channel_oil_hash, c_oil); + rb_pim_oil_del(&c_oil->pim->channel_oil_head, c_oil); pim_channel_oil_free(c_oil); return NULL; diff --git a/pimd/pim_oil.h b/pimd/pim_oil.h index de7fde05d..788ddaa16 100644 --- a/pimd/pim_oil.h +++ b/pimd/pim_oil.h @@ -90,10 +90,13 @@ struct channel_counts { installed: indicate if this entry is installed in the kernel. */ +PREDECL_RBTREE_UNIQ(rb_pim_oil) struct channel_oil { struct pim_instance *pim; + struct rb_pim_oil_item oil_rb; + struct mfcctl oil; int installed; int oil_inherited_rescan; @@ -106,6 +109,12 @@ struct channel_oil { time_t mroute_creation; }; +extern int pim_channel_oil_compare(const struct channel_oil *c1, + const struct channel_oil *c2); +DECLARE_RBTREE_UNIQ(rb_pim_oil, struct channel_oil, oil_rb, + pim_channel_oil_compare) + + extern struct list *pim_channel_oil_list; void pim_oil_init(struct pim_instance *pim); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 0417d0d06..06507b1f4 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -392,16 +392,13 @@ static void pim_zebra_vxlan_replay(void) void pim_scan_oil(struct pim_instance *pim) { - struct listnode *node; - struct listnode *nextnode; struct channel_oil *c_oil; pim->scan_oil_last = pim_time_monotonic_sec(); ++pim->scan_oil_events; - for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode, c_oil)) { + frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) pim_upstream_mroute_iif_update(c_oil, __func__); - } } static int on_rpf_cache_refresh(struct thread *t) |