forked from Mirror/frr
pimd: Convert the upstream_list and hash to a rb tree
Convert the upstream_list and hash to a rb tree, Significant time was being spent in the listnode_add_sort. This reduces this time greatly. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
7315ecdabe
commit
dd3364cb1a
|
@ -914,7 +914,6 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
|
||||||
struct in_addr ifaddr;
|
struct in_addr ifaddr;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct listnode *neighnode;
|
struct listnode *neighnode;
|
||||||
struct listnode *upnode;
|
|
||||||
struct pim_interface *pim_ifp;
|
struct pim_interface *pim_ifp;
|
||||||
struct pim_neighbor *neigh;
|
struct pim_neighbor *neigh;
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
|
@ -1052,8 +1051,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
|
||||||
pim_ifp->pim_dr_election_changes);
|
pim_ifp->pim_dr_election_changes);
|
||||||
|
|
||||||
// FHR
|
// FHR
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
up)) {
|
|
||||||
if (ifp != up->rpf.source_nexthop.interface)
|
if (ifp != up->rpf.source_nexthop.interface)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1215,8 +1213,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
|
||||||
|
|
||||||
// FHR
|
// FHR
|
||||||
print_header = 1;
|
print_header = 1;
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
up)) {
|
|
||||||
if (!up->rpf.source_nexthop.interface)
|
if (!up->rpf.source_nexthop.interface)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1386,7 +1383,6 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
|
||||||
bool uj)
|
bool uj)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct listnode *upnode;
|
|
||||||
struct pim_interface *pim_ifp;
|
struct pim_interface *pim_ifp;
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
int fhr = 0;
|
int fhr = 0;
|
||||||
|
@ -1408,7 +1404,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
|
||||||
pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
|
pim_ifchannels = pim_if_ifchannel_count(pim_ifp);
|
||||||
fhr = 0;
|
fhr = 0;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up))
|
frr_each (rb_pim_upstream, &pim->upstream_head, up)
|
||||||
if (ifp == up->rpf.source_nexthop.interface)
|
if (ifp == up->rpf.source_nexthop.interface)
|
||||||
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
|
if (up->flags & PIM_UPSTREAM_FLAG_MASK_FHR)
|
||||||
fhr++;
|
fhr++;
|
||||||
|
@ -2428,7 +2424,6 @@ static const char *pim_reg_state2brief_str(enum pim_reg_state reg_state,
|
||||||
static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
|
static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
|
||||||
struct prefix_sg *sg, bool uj)
|
struct prefix_sg *sg, bool uj)
|
||||||
{
|
{
|
||||||
struct listnode *upnode;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
time_t now;
|
time_t now;
|
||||||
json_object *json = NULL;
|
json_object *json = NULL;
|
||||||
|
@ -2443,7 +2438,7 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
|
"Iif Source Group State Uptime JoinTimer RSTimer KATimer RefCnt\n");
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
char src_str[INET_ADDRSTRLEN];
|
char src_str[INET_ADDRSTRLEN];
|
||||||
char grp_str[INET_ADDRSTRLEN];
|
char grp_str[INET_ADDRSTRLEN];
|
||||||
char uptime[10];
|
char uptime[10];
|
||||||
|
@ -2715,7 +2710,6 @@ static void pim_show_join_desired_helper(struct pim_instance *pim,
|
||||||
static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
|
static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
|
||||||
bool uj)
|
bool uj)
|
||||||
{
|
{
|
||||||
struct listnode *upnode;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
|
|
||||||
json_object *json = NULL;
|
json_object *json = NULL;
|
||||||
|
@ -2726,7 +2720,7 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"Source Group EvalJD\n");
|
"Source Group EvalJD\n");
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
/* scan all interfaces */
|
/* scan all interfaces */
|
||||||
pim_show_join_desired_helper(pim, vty, up,
|
pim_show_join_desired_helper(pim, vty, up,
|
||||||
json, uj);
|
json, uj);
|
||||||
|
@ -2742,7 +2736,6 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
|
||||||
static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
|
static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
|
||||||
bool uj)
|
bool uj)
|
||||||
{
|
{
|
||||||
struct listnode *upnode;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
json_object *json = NULL;
|
json_object *json = NULL;
|
||||||
json_object *json_group = NULL;
|
json_object *json_group = NULL;
|
||||||
|
@ -2754,7 +2747,7 @@ static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty,
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
"Source Group RpfIface RibNextHop RpfAddress \n");
|
"Source Group RpfIface RibNextHop RpfAddress \n");
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
char src_str[INET_ADDRSTRLEN];
|
char src_str[INET_ADDRSTRLEN];
|
||||||
char grp_str[INET_ADDRSTRLEN];
|
char grp_str[INET_ADDRSTRLEN];
|
||||||
char rpf_nexthop_str[PREFIX_STRLEN];
|
char rpf_nexthop_str[PREFIX_STRLEN];
|
||||||
|
@ -2875,7 +2868,6 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
|
||||||
|
|
||||||
static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
|
static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||||
{
|
{
|
||||||
struct listnode *up_node;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
time_t now = pim_time_monotonic_sec();
|
time_t now = pim_time_monotonic_sec();
|
||||||
json_object *json = NULL;
|
json_object *json = NULL;
|
||||||
|
@ -2892,7 +2884,7 @@ static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
|
||||||
"Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
|
"Source Group RpfIface RpfAddress RibNextHop Metric Pref\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
char src_str[INET_ADDRSTRLEN];
|
char src_str[INET_ADDRSTRLEN];
|
||||||
char grp_str[INET_ADDRSTRLEN];
|
char grp_str[INET_ADDRSTRLEN];
|
||||||
char rpf_addr_str[PREFIX_STRLEN];
|
char rpf_addr_str[PREFIX_STRLEN];
|
||||||
|
@ -3932,11 +3924,8 @@ static void clear_mroute(struct pim_instance *pim)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clean up all upstreams*/
|
/* clean up all upstreams*/
|
||||||
if (pim->upstream_list) {
|
while ((up = rb_pim_upstream_first(&pim->upstream_head))) {
|
||||||
while (pim->upstream_list->count) {
|
pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
|
||||||
up = listnode_head(pim->upstream_list);
|
|
||||||
pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "pim_bsm.h"
|
#include "pim_bsm.h"
|
||||||
#include "pim_vxlan_instance.h"
|
#include "pim_vxlan_instance.h"
|
||||||
#include "pim_oil.h"
|
#include "pim_oil.h"
|
||||||
|
#include "pim_upstream.h"
|
||||||
|
|
||||||
#if defined(HAVE_LINUX_MROUTE_H)
|
#if defined(HAVE_LINUX_MROUTE_H)
|
||||||
#include <linux/mroute.h>
|
#include <linux/mroute.h>
|
||||||
|
@ -108,8 +109,7 @@ struct pim_instance {
|
||||||
struct list *static_routes;
|
struct list *static_routes;
|
||||||
|
|
||||||
// Upstream vrf specific information
|
// Upstream vrf specific information
|
||||||
struct list *upstream_list;
|
struct rb_pim_upstream_head upstream_head;
|
||||||
struct hash *upstream_hash;
|
|
||||||
struct timer_wheel *upstream_sg_wheel;
|
struct timer_wheel *upstream_sg_wheel;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -565,11 +565,9 @@ void pim_msdp_sa_local_update(struct pim_upstream *up)
|
||||||
static void pim_msdp_sa_local_setup(struct pim_instance *pim)
|
static void pim_msdp_sa_local_setup(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *up_node;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, up_node, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up)
|
||||||
pim_msdp_sa_local_update(up);
|
pim_msdp_sa_local_update(up);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* whenever the RP changes we need to re-evaluate the "local" SA-cache */
|
/* whenever the RP changes we need to re-evaluate the "local" SA-cache */
|
||||||
|
|
|
@ -177,7 +177,6 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
|
||||||
struct pim_nexthop_cache *pnc = NULL;
|
struct pim_nexthop_cache *pnc = NULL;
|
||||||
struct pim_nexthop_cache lookup;
|
struct pim_nexthop_cache lookup;
|
||||||
struct zclient *zclient = NULL;
|
struct zclient *zclient = NULL;
|
||||||
struct listnode *upnode = NULL;
|
|
||||||
struct pim_upstream *upstream = NULL;
|
struct pim_upstream *upstream = NULL;
|
||||||
|
|
||||||
zclient = pim_zebra_zclient_get();
|
zclient = pim_zebra_zclient_get();
|
||||||
|
@ -190,8 +189,8 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
|
||||||
/* Release the (*, G)upstream from pnc->upstream_hash,
|
/* Release the (*, G)upstream from pnc->upstream_hash,
|
||||||
* whose Group belongs to the RP getting deleted
|
* whose Group belongs to the RP getting deleted
|
||||||
*/
|
*/
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
|
frr_each (rb_pim_upstream, &pim->upstream_head,
|
||||||
upstream)) {
|
upstream) {
|
||||||
struct prefix grp;
|
struct prefix grp;
|
||||||
struct rp_info *trp_info;
|
struct rp_info *trp_info;
|
||||||
|
|
||||||
|
|
|
@ -86,26 +86,6 @@ int pim_channel_oil_compare(const struct channel_oil *c1,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool pim_oil_equal(const void *arg1, const void *arg2)
|
|
||||||
{
|
|
||||||
const struct channel_oil *c1 = (const struct channel_oil *)arg1;
|
|
||||||
const struct channel_oil *c2 = (const struct channel_oil *)arg2;
|
|
||||||
|
|
||||||
if ((c1->oil.mfcc_mcastgrp.s_addr == c2->oil.mfcc_mcastgrp.s_addr)
|
|
||||||
&& (c1->oil.mfcc_origin.s_addr == c2->oil.mfcc_origin.s_addr))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned int pim_oil_hash_key(const void *arg)
|
|
||||||
{
|
|
||||||
const struct channel_oil *oil = arg;
|
|
||||||
|
|
||||||
return jhash_2words(oil->oil.mfcc_mcastgrp.s_addr,
|
|
||||||
oil->oil.mfcc_origin.s_addr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pim_oil_init(struct pim_instance *pim)
|
void pim_oil_init(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
rb_pim_oil_init(&pim->channel_oil_head);
|
rb_pim_oil_init(&pim->channel_oil_head);
|
||||||
|
|
|
@ -446,7 +446,6 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
|
||||||
struct prefix nht_p;
|
struct prefix nht_p;
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *upnode;
|
|
||||||
|
|
||||||
if (rp_addr.s_addr == INADDR_ANY ||
|
if (rp_addr.s_addr == INADDR_ANY ||
|
||||||
rp_addr.s_addr == INADDR_NONE)
|
rp_addr.s_addr == INADDR_NONE)
|
||||||
|
@ -554,8 +553,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
|
||||||
__PRETTY_FUNCTION__, buf, buf1);
|
__PRETTY_FUNCTION__, buf, buf1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode,
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
up)) {
|
|
||||||
/* Find (*, G) upstream whose RP is not
|
/* Find (*, G) upstream whose RP is not
|
||||||
* configured yet
|
* configured yet
|
||||||
*/
|
*/
|
||||||
|
@ -650,7 +648,7 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
|
||||||
rn->lock);
|
rn->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (up->sg.src.s_addr == INADDR_ANY) {
|
if (up->sg.src.s_addr == INADDR_ANY) {
|
||||||
struct prefix grp;
|
struct prefix grp;
|
||||||
struct rp_info *trp_info;
|
struct rp_info *trp_info;
|
||||||
|
@ -723,7 +721,6 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
|
||||||
bool was_plist = false;
|
bool was_plist = false;
|
||||||
struct rp_info *trp_info;
|
struct rp_info *trp_info;
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *upnode;
|
|
||||||
struct bsgrp_node *bsgrp = NULL;
|
struct bsgrp_node *bsgrp = NULL;
|
||||||
struct bsm_rpinfo *bsrp = NULL;
|
struct bsm_rpinfo *bsrp = NULL;
|
||||||
char grp_str[PREFIX2STR_BUFFER];
|
char grp_str[PREFIX2STR_BUFFER];
|
||||||
|
@ -800,7 +797,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
|
||||||
rp_all = pim_rp_find_match_group(pim, &g_all);
|
rp_all = pim_rp_find_match_group(pim, &g_all);
|
||||||
|
|
||||||
if (rp_all == rp_info) {
|
if (rp_all == rp_info) {
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
/* Find the upstream (*, G) whose upstream address is
|
/* Find the upstream (*, G) whose upstream address is
|
||||||
* same as the deleted RP
|
* same as the deleted RP
|
||||||
*/
|
*/
|
||||||
|
@ -852,7 +849,7 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
|
||||||
|
|
||||||
pim_rp_refresh_group_to_rp_mapping(pim);
|
pim_rp_refresh_group_to_rp_mapping(pim);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
/* Find the upstream (*, G) whose upstream address is same as
|
/* Find the upstream (*, G) whose upstream address is same as
|
||||||
* the deleted RP
|
* the deleted RP
|
||||||
*/
|
*/
|
||||||
|
@ -893,7 +890,6 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
|
||||||
int result = 0;
|
int result = 0;
|
||||||
struct rp_info *rp_info = NULL;
|
struct rp_info *rp_info = NULL;
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *upnode;
|
|
||||||
|
|
||||||
rn = route_node_lookup(pim->rp_table, &group);
|
rn = route_node_lookup(pim->rp_table, &group);
|
||||||
if (!rn) {
|
if (!rn) {
|
||||||
|
@ -942,7 +938,7 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
|
||||||
|
|
||||||
listnode_add_sort(pim->rp_list, rp_info);
|
listnode_add_sort(pim->rp_list, rp_info);
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (up->sg.src.s_addr == INADDR_ANY) {
|
if (up->sg.src.s_addr == INADDR_ANY) {
|
||||||
struct prefix grp;
|
struct prefix grp;
|
||||||
struct rp_info *trp_info;
|
struct rp_info *trp_info;
|
||||||
|
|
|
@ -98,7 +98,6 @@ static void pim_upstream_find_new_children(struct pim_instance *pim,
|
||||||
struct pim_upstream *up)
|
struct pim_upstream *up)
|
||||||
{
|
{
|
||||||
struct pim_upstream *child;
|
struct pim_upstream *child;
|
||||||
struct listnode *ch_node;
|
|
||||||
|
|
||||||
if ((up->sg.src.s_addr != INADDR_ANY)
|
if ((up->sg.src.s_addr != INADDR_ANY)
|
||||||
&& (up->sg.grp.s_addr != INADDR_ANY))
|
&& (up->sg.grp.s_addr != INADDR_ANY))
|
||||||
|
@ -108,7 +107,7 @@ static void pim_upstream_find_new_children(struct pim_instance *pim,
|
||||||
&& (up->sg.grp.s_addr == INADDR_ANY))
|
&& (up->sg.grp.s_addr == INADDR_ANY))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, ch_node, child)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, child) {
|
||||||
if ((up->sg.grp.s_addr != INADDR_ANY)
|
if ((up->sg.grp.s_addr != INADDR_ANY)
|
||||||
&& (child->sg.grp.s_addr == up->sg.grp.s_addr)
|
&& (child->sg.grp.s_addr == up->sg.grp.s_addr)
|
||||||
&& (child != up)) {
|
&& (child != up)) {
|
||||||
|
@ -191,9 +190,8 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
|
||||||
return up;
|
return up;
|
||||||
|
|
||||||
if (PIM_DEBUG_TRACE)
|
if (PIM_DEBUG_TRACE)
|
||||||
zlog_debug(
|
zlog_debug("pim_upstream free vrf:%s %s flags 0x%x",
|
||||||
"pim_upstream free vrf:%s %s flags 0x%x",
|
pim->vrf->name, up->sg_str, up->flags);
|
||||||
pim->vrf->name, up->sg_str, up->flags);
|
|
||||||
|
|
||||||
THREAD_OFF(up->t_ka_timer);
|
THREAD_OFF(up->t_ka_timer);
|
||||||
THREAD_OFF(up->t_rs_timer);
|
THREAD_OFF(up->t_rs_timer);
|
||||||
|
@ -235,8 +233,7 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
|
||||||
listnode_delete(up->parent->sources, up);
|
listnode_delete(up->parent->sources, up);
|
||||||
up->parent = NULL;
|
up->parent = NULL;
|
||||||
|
|
||||||
listnode_delete(pim->upstream_list, up);
|
rb_pim_upstream_del(&pim->upstream_head, up);
|
||||||
hash_release(pim->upstream_hash, up);
|
|
||||||
|
|
||||||
if (notify_msdp) {
|
if (notify_msdp) {
|
||||||
pim_msdp_up_del(pim, &up->sg);
|
pim_msdp_up_del(pim, &up->sg);
|
||||||
|
@ -533,10 +530,9 @@ static int pim_upstream_could_register(struct pim_upstream *up)
|
||||||
* we re-revaluate register setup for existing upstream entries */
|
* we re-revaluate register setup for existing upstream entries */
|
||||||
void pim_upstream_register_reevaluate(struct pim_instance *pim)
|
void pim_upstream_register_reevaluate(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
struct listnode *upnode;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, upnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
/* If FHR is set CouldRegister is True. Also check if the flow
|
/* If FHR is set CouldRegister is True. Also check if the flow
|
||||||
* is actually active; if it is not kat setup will trigger
|
* is actually active; if it is not kat setup will trigger
|
||||||
* source
|
* source
|
||||||
|
@ -639,9 +635,8 @@ void pim_upstream_update_use_rpt(struct pim_upstream *up,
|
||||||
void pim_upstream_reeval_use_rpt(struct pim_instance *pim)
|
void pim_upstream_reeval_use_rpt(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *node;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (up->sg.src.s_addr == INADDR_ANY)
|
if (up->sg.src.s_addr == INADDR_ANY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -756,11 +751,9 @@ void pim_upstream_switch(struct pim_instance *pim, struct pim_upstream *up,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_upstream_compare(void *arg1, void *arg2)
|
int pim_upstream_compare(const struct pim_upstream *up1,
|
||||||
|
const struct pim_upstream *up2)
|
||||||
{
|
{
|
||||||
const struct pim_upstream *up1 = (const struct pim_upstream *)arg1;
|
|
||||||
const struct pim_upstream *up2 = (const struct pim_upstream *)arg2;
|
|
||||||
|
|
||||||
if (ntohl(up1->sg.grp.s_addr) < ntohl(up2->sg.grp.s_addr))
|
if (ntohl(up1->sg.grp.s_addr) < ntohl(up2->sg.grp.s_addr))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -811,7 +804,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
|
||||||
if (ch)
|
if (ch)
|
||||||
ch->upstream = up;
|
ch->upstream = up;
|
||||||
|
|
||||||
up = hash_get(pim->upstream_hash, up, hash_alloc_intern);
|
rb_pim_upstream_add(&pim->upstream_head, up);
|
||||||
/* Set up->upstream_addr as INADDR_ANY, if RP is not
|
/* Set up->upstream_addr as INADDR_ANY, if RP is not
|
||||||
* configured and retain the upstream data structure
|
* configured and retain the upstream data structure
|
||||||
*/
|
*/
|
||||||
|
@ -825,7 +818,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
|
||||||
up->parent = pim_upstream_find_parent(pim, up);
|
up->parent = pim_upstream_find_parent(pim, up);
|
||||||
if (up->sg.src.s_addr == INADDR_ANY) {
|
if (up->sg.src.s_addr == INADDR_ANY) {
|
||||||
up->sources = list_new();
|
up->sources = list_new();
|
||||||
up->sources->cmp = pim_upstream_compare;
|
up->sources->cmp =
|
||||||
|
(int (*)(void *, void *))pim_upstream_compare;
|
||||||
} else
|
} else
|
||||||
up->sources = NULL;
|
up->sources = NULL;
|
||||||
|
|
||||||
|
@ -889,8 +883,6 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listnode_add_sort(pim->upstream_list, up);
|
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_TRACE) {
|
if (PIM_DEBUG_PIM_TRACE) {
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: Created Upstream %s upstream_addr %s ref count %d increment",
|
"%s: Created Upstream %s upstream_addr %s ref count %d increment",
|
||||||
|
@ -908,7 +900,7 @@ struct pim_upstream *pim_upstream_find(struct pim_instance *pim,
|
||||||
struct pim_upstream *up = NULL;
|
struct pim_upstream *up = NULL;
|
||||||
|
|
||||||
lookup.sg = *sg;
|
lookup.sg = *sg;
|
||||||
up = hash_lookup(pim->upstream_hash, &lookup);
|
up = rb_pim_upstream_find(&pim->upstream_head, &lookup);
|
||||||
return up;
|
return up;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1168,15 +1160,12 @@ void pim_upstream_update_join_desired(struct pim_instance *pim,
|
||||||
void pim_upstream_rpf_genid_changed(struct pim_instance *pim,
|
void pim_upstream_rpf_genid_changed(struct pim_instance *pim,
|
||||||
struct in_addr neigh_addr)
|
struct in_addr neigh_addr)
|
||||||
{
|
{
|
||||||
struct listnode *up_node;
|
|
||||||
struct listnode *up_nextnode;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
|
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
|
||||||
*/
|
*/
|
||||||
for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_TRACE) {
|
if (PIM_DEBUG_PIM_TRACE) {
|
||||||
char neigh_str[INET_ADDRSTRLEN];
|
char neigh_str[INET_ADDRSTRLEN];
|
||||||
char rpf_addr_str[PREFIX_STRLEN];
|
char rpf_addr_str[PREFIX_STRLEN];
|
||||||
|
@ -1788,8 +1777,6 @@ int pim_upstream_empty_inherited_olist(struct pim_upstream *up)
|
||||||
*/
|
*/
|
||||||
void pim_upstream_find_new_rpf(struct pim_instance *pim)
|
void pim_upstream_find_new_rpf(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
struct listnode *up_node;
|
|
||||||
struct listnode *up_nextnode;
|
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct pim_rpf old;
|
struct pim_rpf old;
|
||||||
enum pim_rpf_result rpf_result;
|
enum pim_rpf_result rpf_result;
|
||||||
|
@ -1797,7 +1784,7 @@ void pim_upstream_find_new_rpf(struct pim_instance *pim)
|
||||||
/*
|
/*
|
||||||
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
|
* Scan all (S,G) upstreams searching for RPF'(S,G)=neigh_addr
|
||||||
*/
|
*/
|
||||||
for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (up->upstream_addr.s_addr == INADDR_ANY) {
|
if (up->upstream_addr.s_addr == INADDR_ANY) {
|
||||||
if (PIM_DEBUG_PIM_TRACE)
|
if (PIM_DEBUG_PIM_TRACE)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -1837,18 +1824,11 @@ void pim_upstream_terminate(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
|
|
||||||
if (pim->upstream_list) {
|
while ((up = rb_pim_upstream_first(&pim->upstream_head))) {
|
||||||
while (pim->upstream_list->count) {
|
pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
|
||||||
up = listnode_head(pim->upstream_list);
|
|
||||||
pim_upstream_del(pim, up, __PRETTY_FUNCTION__);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_delete(&pim->upstream_list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pim->upstream_hash)
|
rb_pim_upstream_fini(&pim->upstream_head);
|
||||||
hash_free(pim->upstream_hash);
|
|
||||||
pim->upstream_hash = NULL;
|
|
||||||
|
|
||||||
if (pim->upstream_sg_wheel)
|
if (pim->upstream_sg_wheel)
|
||||||
wheel_delete(pim->upstream_sg_wheel);
|
wheel_delete(pim->upstream_sg_wheel);
|
||||||
|
@ -1991,9 +1971,8 @@ static void pim_upstream_sg_running(void *arg)
|
||||||
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim)
|
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *node;
|
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (up->sg.src.s_addr != INADDR_ANY)
|
if (up->sg.src.s_addr != INADDR_ANY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2031,7 +2010,6 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
|
||||||
const char *nlist)
|
const char *nlist)
|
||||||
{
|
{
|
||||||
struct pim_upstream *up;
|
struct pim_upstream *up;
|
||||||
struct listnode *node;
|
|
||||||
struct prefix_list *np;
|
struct prefix_list *np;
|
||||||
struct prefix g;
|
struct prefix g;
|
||||||
enum prefix_list_type apply_new;
|
enum prefix_list_type apply_new;
|
||||||
|
@ -2041,7 +2019,7 @@ void pim_upstream_remove_lhr_star_pimreg(struct pim_instance *pim,
|
||||||
g.family = AF_INET;
|
g.family = AF_INET;
|
||||||
g.prefixlen = IPV4_MAX_PREFIXLEN;
|
g.prefixlen = IPV4_MAX_PREFIXLEN;
|
||||||
|
|
||||||
for (ALL_LIST_ELEMENTS_RO(pim->upstream_list, node, up)) {
|
frr_each (rb_pim_upstream, &pim->upstream_head, up) {
|
||||||
if (up->sg.src.s_addr != INADDR_ANY)
|
if (up->sg.src.s_addr != INADDR_ANY)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2075,11 +2053,5 @@ void pim_upstream_init(struct pim_instance *pim)
|
||||||
wheel_init(router->master, 31000, 100, pim_upstream_hash_key,
|
wheel_init(router->master, 31000, 100, pim_upstream_hash_key,
|
||||||
pim_upstream_sg_running, name);
|
pim_upstream_sg_running, name);
|
||||||
|
|
||||||
snprintf(name, 64, "PIM %s Upstream Hash",
|
rb_pim_upstream_init(&pim->upstream_head);
|
||||||
pim->vrf->name);
|
|
||||||
pim->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
|
|
||||||
pim_upstream_equal, name);
|
|
||||||
|
|
||||||
pim->upstream_list = list_new();
|
|
||||||
pim->upstream_list->cmp = pim_upstream_compare;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ enum pim_upstream_sptbit {
|
||||||
PIM_UPSTREAM_SPTBIT_TRUE
|
PIM_UPSTREAM_SPTBIT_TRUE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
PREDECL_RBTREE_UNIQ(rb_pim_upstream);
|
||||||
/*
|
/*
|
||||||
Upstream (S,G) channel in Joined state
|
Upstream (S,G) channel in Joined state
|
||||||
(S,G) in the "Not Joined" state is not represented
|
(S,G) in the "Not Joined" state is not represented
|
||||||
|
@ -198,6 +199,7 @@ enum pim_upstream_sptbit {
|
||||||
*/
|
*/
|
||||||
struct pim_upstream {
|
struct pim_upstream {
|
||||||
struct pim_instance *pim;
|
struct pim_instance *pim;
|
||||||
|
struct rb_pim_upstream_item upstream_rb;
|
||||||
struct pim_upstream *parent;
|
struct pim_upstream *parent;
|
||||||
struct in_addr upstream_addr; /* Who we are talking to */
|
struct in_addr upstream_addr; /* Who we are talking to */
|
||||||
struct in_addr upstream_register; /*Who we received a register from*/
|
struct in_addr upstream_register; /*Who we received a register from*/
|
||||||
|
@ -326,7 +328,11 @@ void pim_upstream_init(struct pim_instance *pim);
|
||||||
void pim_upstream_terminate(struct pim_instance *pim);
|
void pim_upstream_terminate(struct pim_instance *pim);
|
||||||
|
|
||||||
void join_timer_start(struct pim_upstream *up);
|
void join_timer_start(struct pim_upstream *up);
|
||||||
int pim_upstream_compare(void *arg1, void *arg2);
|
int pim_upstream_compare(const struct pim_upstream *up1,
|
||||||
|
const struct pim_upstream *up2);
|
||||||
|
DECLARE_RBTREE_UNIQ(rb_pim_upstream, struct pim_upstream, upstream_rb,
|
||||||
|
pim_upstream_compare)
|
||||||
|
|
||||||
void pim_upstream_register_reevaluate(struct pim_instance *pim);
|
void pim_upstream_register_reevaluate(struct pim_instance *pim);
|
||||||
|
|
||||||
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim);
|
void pim_upstream_add_lhr_star_pimreg(struct pim_instance *pim);
|
||||||
|
|
Loading…
Reference in a new issue