From fdab29403786a385d40182967f0776fb4c44a8f6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 3 May 2021 15:07:44 +0200 Subject: [PATCH] pimd: cleanup & convert bsm_rpinfo to TS list Signed-off-by: David Lamparter --- pimd/pim_bsm.c | 114 +++++++++++++++++++++---------------------------- pimd/pim_bsm.h | 21 ++++++--- pimd/pim_cmd.c | 106 +++++++++++++++++++-------------------------- pimd/pim_rp.c | 2 +- 4 files changed, 110 insertions(+), 133 deletions(-) diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index 3fabd10ba2..3fbe3317ba 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -43,7 +43,7 @@ static inline void pim_g2rp_timer_restart(struct bsm_rpinfo *bsrp, /* Memory Types */ DEFINE_MTYPE_STATIC(PIMD, PIM_BSGRP_NODE, "PIM BSR advertised grp info"); -DEFINE_MTYPE_STATIC(PIMD, PIM_BSRP_NODE, "PIM BSR advertised RP info"); +DEFINE_MTYPE_STATIC(PIMD, PIM_BSRP_INFO, "PIM BSR advertised RP info"); DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_FRAG, "PIM BSM fragment"); DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_PKT_VAR_MEM, "PIM BSM Packet"); @@ -63,12 +63,24 @@ void pim_bsm_write_config(struct vty *vty, struct interface *ifp) } } +static void pim_bsm_rpinfo_free(struct bsm_rpinfo *bsrp_info) +{ + THREAD_OFF(bsrp_info->g2rp_timer); + XFREE(MTYPE_PIM_BSRP_INFO, bsrp_info); +} + +void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head) +{ + struct bsm_rpinfo *bsrp_info; + + while ((bsrp_info = bsm_rpinfos_pop(head))) + pim_bsm_rpinfo_free(bsrp_info); +} + void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node) { - if (bsgrp_node->bsrp_list) - list_delete(&bsgrp_node->bsrp_list); - if (bsgrp_node->partial_bsrp_list) - list_delete(&bsgrp_node->partial_bsrp_list); + pim_bsm_rpinfos_free(bsgrp_node->bsrp_list); + pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list); XFREE(MTYPE_PIM_BSGRP_NODE, bsgrp_node); } @@ -97,8 +109,8 @@ void pim_bsm_frags_free(struct bsm_scope *scope) pim_bsm_frag_free(bsfrag); } -static int pim_g2rp_list_compare(struct bsm_rpinfo *node1, - struct bsm_rpinfo *node2) +int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *node1, + const struct bsm_rpinfo *node2) { /* RP election Algo : * Step-1 : Loweset Rp priority will have higher precedance. @@ -122,27 +134,6 @@ static int pim_g2rp_list_compare(struct bsm_rpinfo *node1, return 0; } -static void pim_free_bsrp_node(struct bsm_rpinfo *bsrp_info) -{ - THREAD_OFF(bsrp_info->g2rp_timer); - XFREE(MTYPE_PIM_BSRP_NODE, bsrp_info); -} - -static struct list *pim_alloc_bsrp_list(void) -{ - struct list *new_list = NULL; - - new_list = list_new(); - - if (!new_list) - return NULL; - - new_list->cmp = (int (*)(void *, void *))pim_g2rp_list_compare; - new_list->del = (void (*)(void *))pim_free_bsrp_node; - - return new_list; -} - static struct bsgrp_node *pim_bsm_new_bsgrp_node(struct route_table *rt, struct prefix *grp) { @@ -157,14 +148,8 @@ static struct bsgrp_node *pim_bsm_new_bsgrp_node(struct route_table *rt, bsgrp = XCALLOC(MTYPE_PIM_BSGRP_NODE, sizeof(struct bsgrp_node)); rn->info = bsgrp; - bsgrp->bsrp_list = pim_alloc_bsrp_list(); - bsgrp->partial_bsrp_list = pim_alloc_bsrp_list(); - - if ((!bsgrp->bsrp_list) || (!bsgrp->partial_bsrp_list)) { - route_unlock_node(rn); - pim_free_bsgrp_data(bsgrp); - return NULL; - } + bsm_rpinfos_init(bsgrp->bsrp_list); + bsm_rpinfos_init(bsgrp->partial_bsrp_list); prefix_copy(&bsgrp->group, grp); return bsgrp; @@ -215,16 +200,13 @@ static int pim_on_bs_timer(struct thread *t) continue; } /* Give grace time for rp to continue for another hold time */ - if ((bsgrp_node->bsrp_list) && (bsgrp_node->bsrp_list->count)) { - bsrp = listnode_head(bsgrp_node->bsrp_list); + bsrp = bsm_rpinfos_first(bsgrp_node->bsrp_list); + if (bsrp) pim_g2rp_timer_restart(bsrp, bsrp->rp_holdtime); - } + /* clear pending list */ - if ((bsgrp_node->partial_bsrp_list) - && (bsgrp_node->partial_bsrp_list->count)) { - list_delete_all_node(bsgrp_node->partial_bsrp_list); - bsgrp_node->pend_rp_cnt = 0; - } + pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list); + bsgrp_node->pend_rp_cnt = 0; } return 0; } @@ -307,7 +289,6 @@ static int pim_on_g2rp_timer(struct thread *t) struct bsm_rpinfo *bsrp; struct bsm_rpinfo *bsrp_node; struct bsgrp_node *bsgrp_node; - struct listnode *bsrp_ln; struct pim_instance *pim; struct rp_info *rp_info; struct route_node *rn; @@ -323,14 +304,17 @@ static int pim_on_g2rp_timer(struct thread *t) bsrp_addr = bsrp->rp_address; /* update elapse for all bsrp nodes */ - for (ALL_LIST_ELEMENTS_RO(bsgrp_node->bsrp_list, bsrp_ln, bsrp_node)) + frr_each_safe (bsm_rpinfos, bsgrp_node->bsrp_list, bsrp_node) { bsrp_node->elapse_time += elapse; - /* remove the expired nodes from the list */ - list_filter_out_nodes(bsgrp_node->bsrp_list, is_hold_time_elapsed); + if (is_hold_time_elapsed(bsrp_node)) { + bsm_rpinfos_del(bsgrp_node->bsrp_list, bsrp_node); + pim_bsm_rpinfo_free(bsrp_node); + } + } /* Get the next elected rp node */ - bsrp = listnode_head(bsgrp_node->bsrp_list); + bsrp = bsm_rpinfos_first(bsgrp_node->bsrp_list); pim = bsgrp_node->scope->pim; rn = route_node_lookup(pim->rp_table, &bsgrp_node->group); @@ -360,8 +344,8 @@ static int pim_on_g2rp_timer(struct thread *t) } } - if ((!bsgrp_node->bsrp_list->count) - && (!bsgrp_node->partial_bsrp_list->count)) { + if (!bsm_rpinfos_count(bsgrp_node->bsrp_list) + && !bsm_rpinfos_count(bsgrp_node->partial_bsrp_list)) { pim_free_bsgrp_node(pim->global_scope.bsrp_table, &bsgrp_node->group); pim_free_bsgrp_data(bsgrp_node); @@ -424,7 +408,6 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node) { struct bsm_rpinfo *active; struct bsm_rpinfo *pend; - struct list *temp; struct rp_info *rp_info; struct route_node *rn; struct pim_instance *pim; @@ -433,11 +416,14 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node) bool had_rp_node = true; pim = bsgrp_node->scope->pim; - active = listnode_head(bsgrp_node->bsrp_list); + active = bsm_rpinfos_first(bsgrp_node->bsrp_list); /* Remove nodes with hold time 0 & check if list still has a head */ - list_filter_out_nodes(bsgrp_node->partial_bsrp_list, is_hold_time_zero); - pend = listnode_head(bsgrp_node->partial_bsrp_list); + frr_each_safe (bsm_rpinfos, bsgrp_node->partial_bsrp_list, pend) + if (is_hold_time_zero(pend)) + bsm_rpinfos_del(bsgrp_node->partial_bsrp_list, pend); + + pend = bsm_rpinfos_first(bsgrp_node->partial_bsrp_list); if (!str2prefix("224.0.0.0/4", &group_all)) return; @@ -545,14 +531,12 @@ static void pim_instate_pend_list(struct bsgrp_node *bsgrp_node) * pend is head of bsrp list * So check appriate head after swap and clean the new partial list */ - temp = bsgrp_node->bsrp_list; - bsgrp_node->bsrp_list = bsgrp_node->partial_bsrp_list; - bsgrp_node->partial_bsrp_list = temp; + bsm_rpinfos_swap_all(bsgrp_node->bsrp_list, + bsgrp_node->partial_bsrp_list); - if (active) { + if (active) pim_g2rp_timer_stop(active); - list_delete_all_node(bsgrp_node->partial_bsrp_list); - } + pim_bsm_rpinfos_free(bsgrp_node->partial_bsrp_list); } static bool pim_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr, @@ -1038,7 +1022,7 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim, uint8_t hashMask_len = pim->global_scope.hashMasklen; /*memory allocation for bsm_rpinfo */ - bsm_rpinfo = XCALLOC(MTYPE_PIM_BSRP_NODE, sizeof(*bsm_rpinfo)); + bsm_rpinfo = XCALLOC(MTYPE_PIM_BSRP_INFO, sizeof(*bsm_rpinfo)); bsm_rpinfo->rp_prio = rp->rp_pri; bsm_rpinfo->rp_holdtime = rp->rp_holdtime; @@ -1052,7 +1036,7 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim, /* update hash for this rp node */ bsm_rpinfo->hash = hash_calc_on_grp_rp(grpnode->group, rp->rpaddr.addr, hashMask_len); - if (listnode_add_sort_nodup(grpnode->partial_bsrp_list, bsm_rpinfo)) { + if (bsm_rpinfos_add(grpnode->partial_bsrp_list, bsm_rpinfo) == NULL) { if (PIM_DEBUG_BSM) zlog_debug( "%s, bs_rpinfo node added to the partial bs_rplist.", @@ -1063,7 +1047,7 @@ static bool pim_install_bsm_grp_rp(struct pim_instance *pim, if (PIM_DEBUG_BSM) zlog_debug("%s: list node not added", __func__); - XFREE(MTYPE_PIM_BSRP_NODE, bsm_rpinfo); + XFREE(MTYPE_PIM_BSRP_INFO, bsm_rpinfo); return false; } @@ -1081,7 +1065,7 @@ static void pim_update_pending_rp_cnt(struct bsm_scope *sz, zlog_debug( "%s,Received a new BSM ,so clear the pending bs_rpinfo list.", __func__); - list_delete_all_node(bsgrp->partial_bsrp_list); + pim_bsm_rpinfos_free(bsgrp->partial_bsrp_list); bsgrp->pend_rp_cnt = total_rp_count; } } else diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h index eee2a652dd..dbfeeceec8 100644 --- a/pimd/pim_bsm.h +++ b/pimd/pim_bsm.h @@ -26,7 +26,6 @@ #include "if.h" #include "vty.h" #include "typesafe.h" -#include "linklist.h" #include "table.h" #include "pim_rp.h" #include "pim_msg.h" @@ -89,22 +88,29 @@ struct bsm_frag { DECLARE_DLIST(bsm_frags, struct bsm_frag, item); +PREDECL_SORTLIST_UNIQ(bsm_rpinfos); + /* This is the group node of the bsrp table in scope. * this node maintains the list of rp for the group. */ struct bsgrp_node { struct prefix group; /* Group range */ struct bsm_scope *scope; /* Back ptr to scope */ - struct list *bsrp_list; /* list of RPs adv by BSR */ - struct list *partial_bsrp_list; /* maintained until all RPs received */ + + /* RPs advertised by BSR, and temporary list while receiving new set */ + struct bsm_rpinfos_head bsrp_list[1]; + struct bsm_rpinfos_head partial_bsrp_list[1]; + int pend_rp_cnt; /* Total RP - Received RP */ uint16_t frag_tag; /* frag tag to identify the fragment */ }; -/* This is the list node of bsrp_list and partial bsrp list in - * bsgrp_node. Hold info of each RP received for the group +/* Items on [partial_]bsrp_list above. + * Holds info of each candidate RP received for the bsgrp_node's prefix. */ struct bsm_rpinfo { + struct bsm_rpinfos_item item; + uint32_t hash; /* Hash Value as per RFC 7761 4.7.2 */ uint32_t elapse_time; /* upd at expiry of elected RP node */ uint16_t rp_prio; /* RP priority */ @@ -114,6 +120,10 @@ struct bsm_rpinfo { struct thread *g2rp_timer; /* Run only for elected RP node */ }; +extern int pim_bsm_rpinfo_cmp(const struct bsm_rpinfo *a, + const struct bsm_rpinfo *b); +DECLARE_SORTLIST_UNIQ(bsm_rpinfos, struct bsm_rpinfo, item, pim_bsm_rpinfo_cmp); + /* Structures to extract Bootstrap Message header and Grp to RP Mappings * ===================================================================== * BSM Format: @@ -206,6 +216,7 @@ struct bsgrp_node *pim_bsm_get_bsgrp_node(struct bsm_scope *scope, struct prefix *grp); void pim_bs_timer_stop(struct bsm_scope *scope); void pim_bsm_frags_free(struct bsm_scope *scope); +void pim_bsm_rpinfos_free(struct bsm_rpinfos_head *head); void pim_free_bsgrp_data(struct bsgrp_node *bsgrp_node); void pim_free_bsgrp_node(struct route_table *rt, struct prefix *grp); #endif diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 9682746da9..4b72bcb4c3 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -3159,7 +3159,6 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim, struct vty *vty, bool uj) { struct bsgrp_node *bsgrp; - struct listnode *rpnode; struct bsm_rpinfo *bsm_rp; struct route_node *rn; char bsr_str[INET_ADDRSTRLEN]; @@ -3208,42 +3207,33 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim, vty_out(vty, "(ACTIVE)\n"); } - if (bsgrp->bsrp_list) { - for (ALL_LIST_ELEMENTS_RO(bsgrp->bsrp_list, rpnode, - bsm_rp)) { - char rp_str[INET_ADDRSTRLEN]; + frr_each (bsm_rpinfos, bsgrp->bsrp_list, bsm_rp) { + char rp_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", - bsm_rp->rp_address, rp_str, - sizeof(rp_str)); + pim_inet4_dump("", bsm_rp->rp_address, + rp_str, sizeof(rp_str)); - if (uj) { - json_row = json_object_new_object(); - json_object_string_add( - json_row, "Rp Address", rp_str); - json_object_int_add( - json_row, "Rp HoldTime", - bsm_rp->rp_holdtime); - json_object_int_add(json_row, - "Rp Priority", - bsm_rp->rp_prio); - json_object_int_add(json_row, - "Hash Val", - bsm_rp->hash); - json_object_object_add( - json_group, rp_str, json_row); + if (uj) { + json_row = json_object_new_object(); + json_object_string_add(json_row, "Rp Address", + rp_str); + json_object_int_add(json_row, "Rp HoldTime", + bsm_rp->rp_holdtime); + json_object_int_add(json_row, "Rp Priority", + bsm_rp->rp_prio); + json_object_int_add(json_row, "Hash Val", + bsm_rp->hash); + json_object_object_add(json_group, rp_str, + json_row); - } else { - vty_out(vty, - "%-15s %-15u %-15u %-15u\n", - rp_str, bsm_rp->rp_prio, - bsm_rp->rp_holdtime, - bsm_rp->hash); - } + } else { + vty_out(vty, "%-15s %-15u %-15u %-15u\n", + rp_str, bsm_rp->rp_prio, + bsm_rp->rp_holdtime, bsm_rp->hash); } - if (!bsgrp->bsrp_list->count && !uj) - vty_out(vty, "Active List is empty.\n"); } + if (!bsm_rpinfos_count(bsgrp->bsrp_list) && !uj) + vty_out(vty, "Active List is empty.\n"); if (uj) { json_object_int_add(json_group, "Pending RP count", @@ -3258,40 +3248,32 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim, "Hash"); } - if (bsgrp->partial_bsrp_list) { - for (ALL_LIST_ELEMENTS_RO(bsgrp->partial_bsrp_list, - rpnode, bsm_rp)) { - char rp_str[INET_ADDRSTRLEN]; + frr_each (bsm_rpinfos, bsgrp->partial_bsrp_list, bsm_rp) { + char rp_str[INET_ADDRSTRLEN]; - pim_inet4_dump("", bsm_rp->rp_address, - rp_str, sizeof(rp_str)); + pim_inet4_dump("", bsm_rp->rp_address, rp_str, + sizeof(rp_str)); - if (uj) { - json_row = json_object_new_object(); - json_object_string_add( - json_row, "Rp Address", rp_str); - json_object_int_add( - json_row, "Rp HoldTime", - bsm_rp->rp_holdtime); - json_object_int_add(json_row, - "Rp Priority", - bsm_rp->rp_prio); - json_object_int_add(json_row, - "Hash Val", - bsm_rp->hash); - json_object_object_add( - json_group, rp_str, json_row); - } else { - vty_out(vty, - "%-15s %-15u %-15u %-15u\n", - rp_str, bsm_rp->rp_prio, - bsm_rp->rp_holdtime, - bsm_rp->hash); - } + if (uj) { + json_row = json_object_new_object(); + json_object_string_add(json_row, "Rp Address", + rp_str); + json_object_int_add(json_row, "Rp HoldTime", + bsm_rp->rp_holdtime); + json_object_int_add(json_row, "Rp Priority", + bsm_rp->rp_prio); + json_object_int_add(json_row, "Hash Val", + bsm_rp->hash); + json_object_object_add(json_group, rp_str, + json_row); + } else { + vty_out(vty, "%-15s %-15u %-15u %-15u\n", + rp_str, bsm_rp->rp_prio, + bsm_rp->rp_holdtime, bsm_rp->hash); } - if (!bsgrp->partial_bsrp_list->count && !uj) - vty_out(vty, "Partial List is empty\n"); } + if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj) + vty_out(vty, "Partial List is empty\n"); if (!uj) vty_out(vty, "\n"); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index dbba6b66d8..feaeea929d 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -702,7 +702,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr, bsgrp = pim_bsm_get_bsgrp_node(&pim->global_scope, &group); if (bsgrp) { - bsrp = listnode_head(bsgrp->bsrp_list); + bsrp = bsm_rpinfos_first(bsgrp->bsrp_list); if (bsrp) { if (PIM_DEBUG_PIM_TRACE) { char bsrp_str[INET_ADDRSTRLEN]; -- 2.39.5