Merge pull request #5601 from donaldsharp/pim_rb

Pim rb
This commit is contained in:
Donatas Abraitis 2020-01-05 22:07:00 +02:00 committed by GitHub
commit 00a93d03a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 78 additions and 142 deletions

View File

@ -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++;
@ -1975,7 +1971,6 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
const char *src_or_group, const char *group, bool uj) const char *src_or_group, const char *group, bool uj)
{ {
struct channel_oil *c_oil; struct channel_oil *c_oil;
struct listnode *node;
json_object *json = NULL; json_object *json = NULL;
json_object *json_group = NULL; json_object *json_group = NULL;
json_object *json_ifp_in = NULL; json_object *json_ifp_in = NULL;
@ -1994,7 +1989,7 @@ static void pim_show_state(struct pim_instance *pim, struct vty *vty,
"\nActive Source Group RPT IIF OIL\n"); "\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 grp_str[INET_ADDRSTRLEN];
char src_str[INET_ADDRSTRLEN]; char src_str[INET_ADDRSTRLEN];
char in_ifname[INTERFACE_NAMSIZ + 1]; char in_ifname[INTERFACE_NAMSIZ + 1];
@ -2429,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;
@ -2444,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];
@ -2716,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;
@ -2727,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);
@ -2743,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;
@ -2755,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];
@ -2876,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;
@ -2893,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];
@ -3933,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__);
}
} }
} }
@ -5420,7 +5408,7 @@ static void show_mroute(struct pim_instance *pim, struct vty *vty,
now = pim_time_monotonic_sec(); now = pim_time_monotonic_sec();
/* print list of PIM and IGMP routes */ /* 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; found_oif = 0;
first = 1; first = 1;
if (!c_oil->installed && !uj) if (!c_oil->installed && !uj)
@ -5828,7 +5816,7 @@ DEFUN (clear_ip_mroute_count,
return CMD_WARNING; return CMD_WARNING;
pim = vrf->info; 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) if (!c_oil->installed)
continue; continue;
@ -5863,7 +5851,7 @@ static void show_mroute_count(struct pim_instance *pim, struct vty *vty)
"Source Group LastUsed Packets Bytes WrongIf \n"); "Source Group LastUsed Packets Bytes WrongIf \n");
/* Print PIM and IGMP route counts */ /* 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 group_str[INET_ADDRSTRLEN];
char source_str[INET_ADDRSTRLEN]; char source_str[INET_ADDRSTRLEN];
@ -5968,7 +5956,7 @@ static void show_mroute_summary(struct pim_instance *pim, struct vty *vty)
vty_out(vty, "Mroute Type Installed/Total\n"); 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->installed) {
if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY) if (c_oil->oil.mfcc_origin.s_addr == INADDR_ANY)
starg_sw_mroute_cnt++; starg_sw_mroute_cnt++;

View File

@ -1113,8 +1113,10 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
} }
if (pim_is_group_224_0_0_0_24(group_addr)) { if (pim_is_group_224_0_0_0_24(group_addr)) {
zlog_warn("%s: Group specified is part of 224.0.0.0/24", if (PIM_DEBUG_IGMP_TRACE)
__PRETTY_FUNCTION__); zlog_debug(
"%s: Group specified %s is part of 224.0.0.0/24",
__PRETTY_FUNCTION__, inet_ntoa(group_addr));
return NULL; return NULL;
} }
/* /*

View File

@ -28,6 +28,8 @@
#include "pim_assert.h" #include "pim_assert.h"
#include "pim_bsm.h" #include "pim_bsm.h"
#include "pim_vxlan_instance.h" #include "pim_vxlan_instance.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>
@ -107,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;
/* /*
@ -119,8 +120,7 @@ struct pim_instance {
int iface_vif_index[MAXVIFS]; int iface_vif_index[MAXVIFS];
struct list *channel_oil_list; struct rb_pim_oil_head channel_oil_head;
struct hash *channel_oil_hash;
struct pim_msdp msdp; struct pim_msdp msdp;
struct pim_vxlan_instance vxlan; struct pim_vxlan_instance vxlan;

View File

@ -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 */

View File

@ -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;

View File

@ -64,8 +64,8 @@ char *pim_channel_oil_dump(struct channel_oil *c_oil, char *buf, size_t size)
return buf; return buf;
} }
static int pim_channel_oil_compare(struct channel_oil *c1, int pim_channel_oil_compare(const struct channel_oil *c1,
struct channel_oil *c2) const struct channel_oil *c2)
{ {
if (ntohl(c1->oil.mfcc_mcastgrp.s_addr) if (ntohl(c1->oil.mfcc_mcastgrp.s_addr)
< ntohl(c2->oil.mfcc_mcastgrp.s_addr)) < ntohl(c2->oil.mfcc_mcastgrp.s_addr))
@ -86,48 +86,19 @@ static int pim_channel_oil_compare(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)
{ {
char hash_name[64]; rb_pim_oil_init(&pim->channel_oil_head);
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;
} }
void pim_oil_terminate(struct pim_instance *pim) void pim_oil_terminate(struct pim_instance *pim)
{ {
if (pim->channel_oil_list) struct channel_oil *c_oil;
list_delete(&pim->channel_oil_list);
if (pim->channel_oil_hash) while ((c_oil = rb_pim_oil_pop(&pim->channel_oil_head)))
hash_free(pim->channel_oil_hash); pim_channel_oil_free(c_oil);
pim->channel_oil_hash = NULL;
rb_pim_oil_fini(&pim->channel_oil_head);
} }
void pim_channel_oil_free(struct channel_oil *c_oil) void pim_channel_oil_free(struct channel_oil *c_oil)
@ -144,7 +115,7 @@ struct channel_oil *pim_find_channel_oil(struct pim_instance *pim,
lookup.oil.mfcc_mcastgrp = sg->grp; lookup.oil.mfcc_mcastgrp = sg->grp;
lookup.oil.mfcc_origin = sg->src; 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; return c_oil;
} }
@ -187,7 +158,6 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
c_oil->oil.mfcc_mcastgrp = sg->grp; c_oil->oil.mfcc_mcastgrp = sg->grp;
c_oil->oil.mfcc_origin = sg->src; 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.mfcc_parent = MAXVIFS;
c_oil->oil_ref_count = 1; c_oil->oil_ref_count = 1;
@ -195,7 +165,7 @@ struct channel_oil *pim_channel_oil_add(struct pim_instance *pim,
c_oil->up = pim_upstream_find(pim, sg); c_oil->up = pim_upstream_find(pim, sg);
c_oil->pim = pim; 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) if (PIM_DEBUG_MROUTE)
zlog_debug("%s(%s): c_oil %s add", zlog_debug("%s(%s): c_oil %s add",
@ -224,8 +194,7 @@ struct channel_oil *pim_channel_oil_del(struct channel_oil *c_oil,
* called by list_delete_all_node() * called by list_delete_all_node()
*/ */
c_oil->up = NULL; c_oil->up = NULL;
listnode_delete(c_oil->pim->channel_oil_list, c_oil); rb_pim_oil_del(&c_oil->pim->channel_oil_head, c_oil);
hash_release(c_oil->pim->channel_oil_hash, c_oil);
pim_channel_oil_free(c_oil); pim_channel_oil_free(c_oil);
return NULL; return NULL;

View File

@ -90,10 +90,13 @@ struct channel_counts {
installed: indicate if this entry is installed in the kernel. installed: indicate if this entry is installed in the kernel.
*/ */
PREDECL_RBTREE_UNIQ(rb_pim_oil)
struct channel_oil { struct channel_oil {
struct pim_instance *pim; struct pim_instance *pim;
struct rb_pim_oil_item oil_rb;
struct mfcctl oil; struct mfcctl oil;
int installed; int installed;
int oil_inherited_rescan; int oil_inherited_rescan;
@ -106,6 +109,12 @@ struct channel_oil {
time_t mroute_creation; 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; extern struct list *pim_channel_oil_list;
void pim_oil_init(struct pim_instance *pim); void pim_oil_init(struct pim_instance *pim);

View File

@ -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;

View File

@ -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;
} }

View File

@ -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);

View File

@ -392,16 +392,13 @@ static void pim_zebra_vxlan_replay(void)
void pim_scan_oil(struct pim_instance *pim) void pim_scan_oil(struct pim_instance *pim)
{ {
struct listnode *node;
struct listnode *nextnode;
struct channel_oil *c_oil; struct channel_oil *c_oil;
pim->scan_oil_last = pim_time_monotonic_sec(); pim->scan_oil_last = pim_time_monotonic_sec();
++pim->scan_oil_events; ++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__); pim_upstream_mroute_iif_update(c_oil, __func__);
}
} }
static int on_rpf_cache_refresh(struct thread *t) static int on_rpf_cache_refresh(struct thread *t)