int hold_time);
/* 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_BSM_INFO, "PIM BSM Info")
-DEFINE_MTYPE_STATIC(PIMD, PIM_BSM_PKT_VAR_MEM, "PIM BSM Packet")
+DEFINE_MTYPE_STATIC(PIMD, PIM_BSGRP_NODE, "PIM BSR advertised grp 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");
/* All bsm packets forwarded shall be fit within ip mtu less iphdr(max) */
#define MAX_IP_HDR_LEN 24
}
}
+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);
}
}
}
-static void pim_bsm_node_free(struct bsm_info *bsm)
+static void pim_bsm_frag_free(struct bsm_frag *bsfrag)
{
- XFREE(MTYPE_PIM_BSM_PKT_VAR_MEM, bsm->bsm);
- XFREE(MTYPE_PIM_BSM_INFO, bsm);
+ XFREE(MTYPE_PIM_BSM_FRAG, bsfrag);
}
-static int pim_g2rp_list_compare(struct bsm_rpinfo *node1,
- struct bsm_rpinfo *node2)
+void pim_bsm_frags_free(struct bsm_scope *scope)
+{
+ struct bsm_frag *bsfrag;
+
+ while ((bsfrag = bsm_frags_pop(scope->bsm_frags)))
+ pim_bsm_frag_free(bsfrag);
+}
+
+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.
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)
{
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;
scope->current_bsr_first_ts = 0;
scope->current_bsr_last_ts = 0;
scope->bsm_frag_tag = 0;
- list_delete_all_node(scope->bsm_list);
+ pim_bsm_frags_free(scope);
for (rn = route_top(scope->bsrp_table); rn; rn = route_next(rn)) {
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;
}
pim->global_scope.accept_nofwd_bsm = true;
pim->global_scope.state = NO_INFO;
pim->global_scope.pim = pim;
- pim->global_scope.bsm_list = list_new();
- pim->global_scope.bsm_list->del = (void (*)(void *))pim_bsm_node_free;
+ bsm_frags_init(pim->global_scope.bsm_frags);
pim_bs_timer_start(&pim->global_scope, PIM_BS_TIME);
}
struct bsgrp_node *bsgrp;
pim_bs_timer_stop(&pim->global_scope);
-
- if (pim->global_scope.bsm_list)
- list_delete(&pim->global_scope.bsm_list);
+ pim_bsm_frags_free(&pim->global_scope);
for (rn = route_top(pim->global_scope.bsrp_table); rn;
rn = route_next(rn)) {
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;
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);
}
}
- 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);
{
struct bsm_rpinfo *active;
struct bsm_rpinfo *pend;
- struct list *temp;
struct rp_info *rp_info;
struct route_node *rn;
struct pim_instance *pim;
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;
* 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,
struct in_addr dst_addr;
struct pim_interface *pim_ifp;
struct bsm_scope *scope;
- struct listnode *bsm_ln;
- struct bsm_info *bsminfo;
+ struct bsm_frag *bsfrag;
char neigh_src_str[INET_ADDRSTRLEN];
uint32_t pim_mtu;
bool no_fwd = true;
scope = &pim_ifp->pim->global_scope;
- if (!scope->bsm_list->count) {
+ if (!bsm_frags_count(scope->bsm_frags)) {
if (PIM_DEBUG_BSM)
zlog_debug("%s: BSM list for the scope is empty",
__func__);
pim_mtu = ifp->mtu - MAX_IP_HDR_LEN;
pim_hello_require(ifp);
- for (ALL_LIST_ELEMENTS_RO(scope->bsm_list, bsm_ln, bsminfo)) {
- if (pim_mtu < bsminfo->size) {
- ret = pim_bsm_frag_send(bsminfo->bsm, bsminfo->size,
- ifp, pim_mtu, dst_addr, no_fwd);
+ frr_each (bsm_frags, scope->bsm_frags, bsfrag) {
+ if (pim_mtu < bsfrag->size) {
+ ret = pim_bsm_frag_send(bsfrag->data, bsfrag->size, ifp,
+ pim_mtu, dst_addr, no_fwd);
if (!ret) {
if (PIM_DEBUG_BSM)
zlog_debug(
}
} else {
/* Pim header needs to be constructed */
- pim_msg_build_header(bsminfo->bsm, bsminfo->size,
+ pim_msg_build_header(bsfrag->data, bsfrag->size,
PIM_MSG_TYPE_BOOTSTRAP, no_fwd);
- ret = pim_bsm_send_intf(bsminfo->bsm, bsminfo->size,
- ifp, dst_addr);
+ ret = pim_bsm_send_intf(bsfrag->data, bsfrag->size, ifp,
+ dst_addr);
if (!ret) {
if (PIM_DEBUG_BSM)
zlog_debug(
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;
/* 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.",
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;
}
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
int sz = PIM_GBL_SZ_ID;
struct bsmmsg_grpinfo *msg_grp;
struct pim_interface *pim_ifp = NULL;
- struct bsm_info *bsminfo;
+ struct bsm_frag *bsfrag;
struct pim_instance *pim;
char bsr_str[INET_ADDRSTRLEN];
uint16_t frag_tag;
}
}
} else if (if_lookup_exact_address(&ip_hdr->ip_dst, AF_INET,
- pim->vrf_id)) {
+ pim->vrf->vrf_id)) {
/* Unicast BSM received - if ucast bsm not enabled on
* the interface, drop it
*/
pim_ifp->pim->global_scope.bsm_frag_tag,
frag_tag);
}
- list_delete_all_node(pim_ifp->pim->global_scope.bsm_list);
+ pim_bsm_frags_free(&pim_ifp->pim->global_scope);
pim_ifp->pim->global_scope.bsm_frag_tag = frag_tag;
}
if (!no_fwd) {
pim_bsm_fwd_whole_sz(pim_ifp->pim, buf, buf_size, sz);
- bsminfo = XCALLOC(MTYPE_PIM_BSM_INFO, sizeof(struct bsm_info));
-
- bsminfo->bsm = XCALLOC(MTYPE_PIM_BSM_PKT_VAR_MEM, buf_size);
+ bsfrag = XCALLOC(MTYPE_PIM_BSM_FRAG,
+ sizeof(struct bsm_frag) + buf_size);
- bsminfo->size = buf_size;
- memcpy(bsminfo->bsm, buf, buf_size);
- listnode_add(pim_ifp->pim->global_scope.bsm_list, bsminfo);
+ bsfrag->size = buf_size;
+ memcpy(bsfrag->data, buf, buf_size);
+ bsm_frags_add_tail(pim_ifp->pim->global_scope.bsm_frags,
+ bsfrag);
}
return 0;