pimd: Remove almost duplicate pim->ifchannel_list

The pim->ifchannel_list can be duplicated by iterating
over each vrf and then over each pim_ifp->pim_ifchannel_list
Since list handling is taking allot of time at scale
convert over to using this value.

Additionally clean up pim_cmd.c to have helper functions
to handle the actual encoding of data for output.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2017-07-31 09:58:42 -04:00
parent 07a2935559
commit 1a8a3da8c2
4 changed files with 369 additions and 296 deletions

View File

@ -176,31 +176,18 @@ static void pim_if_membership_refresh(struct interface *ifp)
pim_ifchannel_delete_on_noinfo(ifp);
}
static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
static void pim_show_assert_helper(struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch,
time_t now)
{
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct listnode *ch_node;
struct in_addr ifaddr;
time_t now;
now = pim_time_monotonic_sec();
vty_out(vty,
"Interface Address Source Group State Winner Uptime Timer\n");
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
char winner_str[INET_ADDRSTRLEN];
struct in_addr ifaddr;
char uptime[10];
char timer[10];
pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
@ -220,35 +207,43 @@ static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
ch_grp_str,
pim_ifchannel_ifassert_name(ch->ifassert_state),
winner_str, uptime, timer);
} /* scan interface channels */
}
static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
{
struct pim_interface *pim_ifp;
struct listnode *ch_node;
struct pim_ifchannel *ch;
struct in_addr ifaddr;
struct listnode *ch_node;
struct listnode *if_node;
struct interface *ifp;
time_t now;
now = pim_time_monotonic_sec();
vty_out(vty,
"CA: CouldAssert\n"
"ECA: Evaluate CouldAssert\n"
"ATD: AssertTrackingDesired\n"
"eATD: Evaluate AssertTrackingDesired\n\n");
vty_out(vty,
"Interface Address Source Group CA eCA ATD eATD\n");
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
pim_ifp = ch->interface->info;
"Interface Address Source Group State Winner Uptime Timer\n");
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
pim_show_assert_helper(vty, pim_ifp, ch, now);
} /* scan interface channels */
}
}
static void pim_show_assert_internal_helper(struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch)
{
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
struct in_addr ifaddr;
ifaddr = pim_ifp->primary_address;
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
sizeof(ch_src_str));
@ -264,31 +259,47 @@ static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
: "no",
pim_macro_assert_tracking_desired_eval(ch) ? "yes"
: "no");
} /* scan interface channels */
}
static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
static void pim_show_assert_internal(struct pim_instance *pim, struct vty *vty)
{
struct pim_interface *pim_ifp;
struct listnode *ch_node;
struct listnode *if_node;
struct pim_ifchannel *ch;
struct in_addr ifaddr;
struct interface *ifp;
vty_out(vty,
"Interface Address Source Group RPT Pref Metric Address \n");
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
pim_ifp = ch->interface->info;
"CA: CouldAssert\n"
"ECA: Evaluate CouldAssert\n"
"ATD: AssertTrackingDesired\n"
"eATD: Evaluate AssertTrackingDesired\n\n");
vty_out(vty,
"Interface Address Source Group CA eCA ATD eATD\n");
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
pim_show_assert_internal_helper(vty, pim_ifp, ch);
} /* scan interface channels */
}
}
static void pim_show_assert_metric_helper(struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch)
{
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
char addr_str[INET_ADDRSTRLEN];
struct pim_assert_metric am;
struct in_addr ifaddr;
ifaddr = pim_ifp->primary_address;
am = pim_macro_spt_assert_metric(&ch->upstream->rpf,
pim_ifp->primary_address);
@ -304,35 +315,44 @@ static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
ch_grp_str, am.rpt_bit_flag ? "yes" : "no",
am.metric_preference, am.route_metric, addr_str);
} /* scan interface channels */
}
static void pim_show_assert_winner_metric(struct pim_instance *pim,
struct vty *vty)
static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
{
struct pim_interface *pim_ifp;
struct listnode *ch_node;
struct listnode *ch_node, *if_node;
struct pim_ifchannel *ch;
struct in_addr ifaddr;
struct interface *ifp;
vty_out(vty,
"Interface Address Source Group RPT Pref Metric Address \n");
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
pim_ifp = ch->interface->info;
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
pim_show_assert_metric_helper(vty, pim_ifp, ch);
} /* scan interface channels */
}
}
static void pim_show_assert_winner_metric_helper(struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch)
{
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
char addr_str[INET_ADDRSTRLEN];
struct pim_assert_metric *am;
struct in_addr ifaddr;
char pref_str[5];
char metr_str[7];
ifaddr = pim_ifp->primary_address;
am = &ch->ifassert_winner_metric;
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
@ -358,7 +378,29 @@ static void pim_show_assert_winner_metric(struct pim_instance *pim,
ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
ch_grp_str, am->rpt_bit_flag ? "yes" : "no", pref_str,
metr_str, addr_str);
}
static void pim_show_assert_winner_metric(struct pim_instance *pim,
struct vty *vty)
{
struct listnode *ch_node, *if_node;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct interface *ifp;
vty_out(vty,
"Interface Address Source Group RPT Pref Metric Address \n");
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
pim_show_assert_winner_metric_helper(vty, pim_ifp, ch);
} /* scan interface channels */
}
}
static void json_object_pim_ifp_add(struct json_object *json,
@ -392,29 +434,15 @@ static void json_object_pim_ifp_add(struct json_object *json,
json_object_boolean_true_add(json, "lanDelayEnabled");
}
static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
u_char uj)
static void pim_show_membership_helper(struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch,
struct json_object *json)
{
struct pim_interface *pim_ifp;
struct listnode *ch_node;
struct pim_ifchannel *ch;
enum json_type type;
json_object *json = NULL;
json_object *json_iface = NULL;
json_object *json_row = NULL;
json_object *json_tmp = NULL;
json = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
json_object *json_iface = NULL;
json_object *json_row = NULL;
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
sizeof(ch_src_str));
@ -423,7 +451,6 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
json_object_object_get_ex(json, ch->interface->name,
&json_iface);
if (!json_iface) {
json_iface = json_object_new_object();
json_object_pim_ifp_add(json_iface, ch->interface);
@ -440,7 +467,31 @@ static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
? "NOINFO"
: "INCLUDE");
json_object_object_add(json_iface, ch_grp_str, json_row);
}
static void pim_show_membership(struct pim_instance *pim, struct vty *vty,
u_char uj)
{
struct listnode *ch_node, *if_node;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct interface *ifp;
enum json_type type;
json_object *json = NULL;
json_object *json_tmp = NULL;
json = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
pim_show_membership_helper(vty, pim_ifp, ch, json);
} /* scan interface channels */
}
if (uj) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
@ -1553,41 +1604,25 @@ static void pim_show_interface_traffic_single(struct pim_instance *pim,
}
}
static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj)
static void pim_show_join_helper(struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch,
json_object *json,
time_t now,
u_char uj)
{
struct pim_interface *pim_ifp;
struct in_addr ifaddr;
struct listnode *ch_node;
struct pim_ifchannel *ch;
time_t now;
json_object *json = NULL;
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
json_object *json_iface = NULL;
json_object *json_row = NULL;
json_object *json_grp = NULL;
now = pim_time_monotonic_sec();
if (uj)
json = json_object_new_object();
else
vty_out(vty,
"Interface Address Source Group State Uptime Expire Prune\n");
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, ch_node, ch)) {
pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
ifaddr = pim_ifp->primary_address;
char ch_src_str[INET_ADDRSTRLEN];
char ch_grp_str[INET_ADDRSTRLEN];
struct in_addr ifaddr;
char uptime[10];
char expire[10];
char prune[10];
ifaddr = pim_ifp->primary_address;
pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str,
sizeof(ch_src_str));
pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str,
@ -1645,7 +1680,36 @@ static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj)
ch->flags),
uptime, expire, prune);
}
}
static void pim_show_join(struct pim_instance *pim, struct vty *vty, u_char uj)
{
struct listnode *ch_node, *if_node;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct interface *ifp;
time_t now;
json_object *json = NULL;
now = pim_time_monotonic_sec();
if (uj)
json = json_object_new_object();
else
vty_out(vty,
"Interface Address Source Group State Uptime Expire Prune\n");
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
pim_show_join_helper(vty, pim_ifp,
ch, json, now, uj);
} /* scan interface channels */
}
if (uj) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
@ -2382,33 +2446,19 @@ static void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
}
}
static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
static void pim_show_join_desired_helper(struct pim_instance *pim,
struct vty *vty,
struct pim_interface *pim_ifp,
struct pim_ifchannel *ch,
json_object *json,
u_char uj)
{
struct listnode *chnode;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct pim_upstream *up = ch->upstream;
json_object *json_group = NULL;
char src_str[INET_ADDRSTRLEN];
char grp_str[INET_ADDRSTRLEN];
json_object *json = NULL;
json_object *json_group = NULL;
json_object *json_row = NULL;
if (uj)
json = json_object_new_object();
else
vty_out(vty,
"Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
/* scan per-interface (S,G) state */
for (ALL_LIST_ELEMENTS_RO(pim->ifchannel_list, chnode, ch)) {
/* scan all interfaces */
pim_ifp = ch->interface->info;
if (!pim_ifp)
continue;
struct pim_upstream *up = ch->upstream;
pim_inet4_dump("<src?>", up->sg.src, src_str, sizeof(src_str));
pim_inet4_dump("<grp?>", up->sg.grp, grp_str, sizeof(grp_str));
@ -2460,6 +2510,37 @@ static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
? "yes"
: "no");
}
}
static void pim_show_join_desired(struct pim_instance *pim, struct vty *vty,
u_char uj)
{
struct listnode *ch_node, *if_node;
struct pim_interface *pim_ifp;
struct pim_ifchannel *ch;
struct interface *ifp;
json_object *json = NULL;
if (uj)
json = json_object_new_object();
else
vty_out(vty,
"Interface Source Group LostAssert Joins PimInclude JoinDesired EvalJD\n");
/* scan per-interface (S,G) state */
for (ALL_LIST_ELEMENTS_RO(vrf_iflist(pim->vrf_id), if_node, ifp)) {
pim_ifp = ifp->info;
if (!pim_ifp)
continue;
for (ALL_LIST_ELEMENTS_RO(pim_ifp->pim_ifchannel_list,
ch_node, ch)) {
/* scan all interfaces */
pim_show_join_desired_helper(pim, vty,
pim_ifp, ch,
json, uj);
}
}
if (uj) {

View File

@ -56,16 +56,12 @@ void pim_if_init(struct pim_instance *pim)
for (i = 0; i < MAXVIFS; i++)
pim->iface_vif_index[i] = 0;
pim->ifchannel_list = list_new();
pim->ifchannel_list->cmp =
(int (*)(void *, void *))pim_ifchannel_compare;
}
void pim_if_terminate(struct pim_instance *pim)
{
if (pim->ifchannel_list)
list_free(pim->ifchannel_list);
// Nothing to do at this moment
return;
}
static void *if_list_clean(struct pim_interface *pim_ifp)

View File

@ -196,7 +196,6 @@ void pim_ifchannel_delete(struct pim_ifchannel *ch)
*/
listnode_delete(pim_ifp->pim_ifchannel_list, ch);
hash_release(pim_ifp->pim_ifchannel_hash, ch);
listnode_delete(pim_ifp->pim->ifchannel_list, ch);
if (PIM_DEBUG_PIM_TRACE)
zlog_debug("%s: ifchannel entry %s is deleted ",
@ -557,7 +556,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
/* Attach to list */
listnode_add_sort(pim_ifp->pim_ifchannel_list, ch);
ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern);
listnode_add_sort(pim_ifp->pim->ifchannel_list, ch);
up = pim_upstream_add(pim_ifp->pim, sg, NULL, up_flags,
__PRETTY_FUNCTION__, ch);
@ -577,7 +575,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,
listnode_delete(pim_ifp->pim_ifchannel_list, ch);
hash_release(pim_ifp->pim_ifchannel_hash, ch);
listnode_delete(pim_ifp->pim->ifchannel_list, ch);
XFREE(MTYPE_PIM_IFCHANNEL, ch);
return NULL;
}

View File

@ -78,7 +78,6 @@ struct pim_instance {
struct list *rp_list;
struct list *ifchannel_list;
int iface_vif_index[MAXVIFS];
struct list *channel_oil_list;