From 78c16071f99bf3a5df1800a26656c3362eb0ba48 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 17 Mar 2018 20:54:04 -0400 Subject: [PATCH 1/4] pimd: Just call the actual function We do not really need a level of abstraction to call a particular function. Just call it. Signed-off-by: Donald Sharp --- pimd/pim_neighbor.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index dd77e2b084..134dbd8712 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -477,17 +477,6 @@ struct pim_neighbor *pim_neighbor_find_if(struct interface *ifp) return listnode_head(pim_ifp->pim_neighbor_list); } -/* rpf info associated with an upstream entry needs to be re-evaluated - * when an RPF neighbor comes or goes */ -static void pim_neighbor_rpf_update(void) -{ - /* XXX: for the time being piggyback on the timer used on rib changes - * to scan and update the rpf nexthop. This is expensive processing - * and we should be able to optimize neighbor changes differently than - * nexthop changes. */ - sched_rpf_cache_refresh(); -} - struct pim_neighbor * pim_neighbor_add(struct interface *ifp, struct in_addr source_addr, pim_hello_options hello_options, uint16_t holdtime, @@ -556,7 +545,7 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr, pim_rp_setup(pim_ifp->pim); - pim_neighbor_rpf_update(); + sched_rpf_cache_refresh(); return neigh; } @@ -678,7 +667,7 @@ void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh, pim_neighbor_free(neigh); - pim_neighbor_rpf_update(); + sched_rpf_cache_refresh(); } void pim_neighbor_delete_all(struct interface *ifp, const char *delete_message) From da11e32521af32b4db39eeb48f2725e9f3db824d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 17 Mar 2018 21:13:09 -0400 Subject: [PATCH 2/4] pimd: Make the rpf scan per vrf. We know the vrf that we are in when we need to initiate a rescan of the rpf cache. So pass it in and use that information. This should help the rescan at scale with several vrf's cutting out a lot of unnecessary work. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 14 +-- pimd/pim_instance.h | 3 + pimd/pim_neighbor.c | 4 +- pimd/pim_zebra.c | 234 ++++++++++++++++++-------------------------- pimd/pim_zebra.h | 2 +- pimd/pimd.c | 1 - pimd/pimd.h | 1 - 7 files changed, 110 insertions(+), 149 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 803e7bb013..a8935bf80d 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2566,8 +2566,8 @@ static void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, } } -static void show_rpf_refresh_stats(struct vty *vty, time_t now, - json_object *json) +static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim, + time_t now, json_object *json) { char refresh_uptime[10]; @@ -2579,7 +2579,7 @@ static void show_rpf_refresh_stats(struct vty *vty, time_t now, qpim_rpf_cache_refresh_delay_msec); json_object_int_add( json, "rpfCacheRefreshTimer", - pim_time_timer_remain_msec(qpim_rpf_cache_refresher)); + pim_time_timer_remain_msec(pim->rpf_cache_refresher)); json_object_int_add(json, "rpfCacheRefreshRequests", qpim_rpf_cache_refresh_requests); json_object_int_add(json, "rpfCacheRefreshEvents", @@ -2600,7 +2600,7 @@ static void show_rpf_refresh_stats(struct vty *vty, time_t now, "Nexthop Lookups: %lld\n" "Nexthop Lookups Avoided: %lld\n", qpim_rpf_cache_refresh_delay_msec, - pim_time_timer_remain_msec(qpim_rpf_cache_refresher), + pim_time_timer_remain_msec(pim->rpf_cache_refresher), (long long)qpim_rpf_cache_refresh_requests, (long long)qpim_rpf_cache_refresh_events, refresh_uptime, (long long)qpim_nexthop_lookups, @@ -2642,9 +2642,9 @@ static void pim_show_rpf(struct pim_instance *pim, struct vty *vty, u_char uj) if (uj) { json = json_object_new_object(); - show_rpf_refresh_stats(vty, now, json); + show_rpf_refresh_stats(vty, pim, now, json); } else { - show_rpf_refresh_stats(vty, now, json); + show_rpf_refresh_stats(vty, pim, now, json); vty_out(vty, "\n"); vty_out(vty, "Source Group RpfIface RpfAddress RibNextHop Metric Pref\n"); @@ -4337,7 +4337,7 @@ static void pim_cmd_show_ip_multicast_helper(struct pim_instance *pim, vty_out(vty, "\n"); - show_rpf_refresh_stats(vty, now, NULL); + show_rpf_refresh_stats(vty, pim, now, NULL); vty_out(vty, "\n"); diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index 5422e8fe0d..e672c39fdc 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -94,6 +94,9 @@ struct pim_instance { unsigned int keep_alive_time; unsigned int rp_keep_alive_time; + + /* If we need to rescan all our upstreams */ + struct thread *rpf_cache_refresher; }; void pim_vrf_init(void); diff --git a/pimd/pim_neighbor.c b/pimd/pim_neighbor.c index 134dbd8712..20a942b4fd 100644 --- a/pimd/pim_neighbor.c +++ b/pimd/pim_neighbor.c @@ -545,7 +545,7 @@ pim_neighbor_add(struct interface *ifp, struct in_addr source_addr, pim_rp_setup(pim_ifp->pim); - sched_rpf_cache_refresh(); + sched_rpf_cache_refresh(pim_ifp->pim); return neigh; } @@ -667,7 +667,7 @@ void pim_neighbor_delete(struct interface *ifp, struct pim_neighbor *neigh, pim_neighbor_free(neigh); - sched_rpf_cache_refresh(); + sched_rpf_cache_refresh(pim_ifp->pim); } void pim_neighbor_delete_all(struct interface *ifp, const char *delete_message) diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index 81c0cb6efb..ecb97e8e44 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -394,133 +394,105 @@ static int pim_zebra_if_address_del(int command, struct zclient *client, return 0; } -static void scan_upstream_rpf_cache() +static void scan_upstream_rpf_cache(struct pim_instance *pim) { struct listnode *up_node; struct listnode *up_nextnode; struct listnode *node; struct pim_upstream *up; struct interface *ifp; - struct vrf *vrf; - struct pim_instance *pim; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - pim = vrf->info; - if (!pim) + for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, up)) { + enum pim_rpf_result rpf_result; + struct pim_rpf old; + struct prefix nht_p; + + nht_p.family = AF_INET; + nht_p.prefixlen = IPV4_MAX_BITLEN; + nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr; + pim_resolve_upstream_nh(pim, &nht_p); + + old.source_nexthop.interface = up->rpf.source_nexthop.interface; + old.source_nexthop.nbr = up->rpf.source_nexthop.nbr; + rpf_result = pim_rpf_update(pim, up, &old, 0); + + if (rpf_result == PIM_RPF_FAILURE) continue; - for (ALL_LIST_ELEMENTS(pim->upstream_list, up_node, up_nextnode, - up)) { - enum pim_rpf_result rpf_result; - struct pim_rpf old; - struct prefix nht_p; + if (rpf_result == PIM_RPF_CHANGED) { + struct pim_neighbor *nbr; - nht_p.family = AF_INET; - nht_p.prefixlen = IPV4_MAX_BITLEN; - nht_p.u.prefix4.s_addr = up->upstream_addr.s_addr; - pim_resolve_upstream_nh(pim, &nht_p); + nbr = pim_neighbor_find(old.source_nexthop.interface, + old.rpf_addr.u.prefix4); + if (nbr) + pim_jp_agg_remove_group(nbr->upstream_jp_agg, + up); - old.source_nexthop.interface = - up->rpf.source_nexthop.interface; - old.source_nexthop.nbr = up->rpf.source_nexthop.nbr; - rpf_result = pim_rpf_update(pim, up, &old, 0); + /* + * We have detected a case where we might need + * to rescan + * the inherited o_list so do it. + */ + if (up->channel_oil->oil_inherited_rescan) { + pim_upstream_inherited_olist_decide(pim, up); + up->channel_oil->oil_inherited_rescan = 0; + } - if (rpf_result == PIM_RPF_FAILURE) - continue; - - if (rpf_result == PIM_RPF_CHANGED) { - struct pim_neighbor *nbr; - - nbr = pim_neighbor_find( - old.source_nexthop.interface, - old.rpf_addr.u.prefix4); - if (nbr) - pim_jp_agg_remove_group( - nbr->upstream_jp_agg, up); + if (up->join_state == PIM_UPSTREAM_JOINED) { + /* + * If we come up real fast we can be here + * where the mroute has not been installed + * so install it. + */ + if (!up->channel_oil->installed) + pim_mroute_add(up->channel_oil, + __PRETTY_FUNCTION__); /* - * We have detected a case where we might need - * to rescan - * the inherited o_list so do it. + * RFC 4601: 4.5.7. Sending (S,G) + * Join/Prune Messages + * + * Transitions from Joined State + * + * RPF'(S,G) changes not due to an Assert + * + * The upstream (S,G) state machine remains + * in Joined state. Send Join(S,G) to the new + * upstream neighbor, which is the new value + * of RPF'(S,G). Send Prune(S,G) to the old + * upstream neighbor, which is the old value + * of RPF'(S,G). Set the Join Timer (JT) to + * expire after t_periodic seconds. */ - if (up->channel_oil->oil_inherited_rescan) { - pim_upstream_inherited_olist_decide(pim, - up); - up->channel_oil->oil_inherited_rescan = - 0; - } + pim_jp_agg_switch_interface(&old, &up->rpf, up); - if (up->join_state == PIM_UPSTREAM_JOINED) { - /* - * If we come up real fast we can be - * here - * where the mroute has not been - * installed - * so install it. - */ - if (!up->channel_oil->installed) - pim_mroute_add( - up->channel_oil, - __PRETTY_FUNCTION__); + pim_upstream_join_timer_restart(up, &old); + } /* up->join_state == PIM_UPSTREAM_JOINED */ - /* - * RFC 4601: 4.5.7. Sending (S,G) - * Join/Prune Messages - * - * Transitions from Joined State - * - * RPF'(S,G) changes not due to an - * Assert - * - * The upstream (S,G) state machine - * remains in Joined - * state. Send Join(S,G) to the new - * upstream neighbor, which is - * the new value of RPF'(S,G). Send - * Prune(S,G) to the old - * upstream neighbor, which is the old - * value of RPF'(S,G). Set - * the Join Timer (JT) to expire after - * t_periodic seconds. - */ - pim_jp_agg_switch_interface( - &old, &up->rpf, up); + /* FIXME can join_desired actually be changed by + pim_rpf_update() + returning PIM_RPF_CHANGED ? */ + pim_upstream_update_join_desired(pim, up); - pim_upstream_join_timer_restart(up, - &old); - } /* up->join_state == PIM_UPSTREAM_JOINED */ + } /* PIM_RPF_CHANGED */ - /* FIXME can join_desired actually be changed by - pim_rpf_update() - returning PIM_RPF_CHANGED ? */ - pim_upstream_update_join_desired(pim, up); + } /* for (qpim_upstream_list) */ - } /* PIM_RPF_CHANGED */ + FOR_ALL_INTERFACES (pim->vrf, ifp) + if (ifp->info) { + struct pim_interface *pim_ifp = ifp->info; + struct pim_iface_upstream_switch *us; - } /* for (qpim_upstream_list) */ - } + for (ALL_LIST_ELEMENTS_RO(pim_ifp->upstream_switch_list, + node, us)) { + struct pim_rpf rpf; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - pim = vrf->info; - if (!pim) - continue; - - FOR_ALL_INTERFACES (pim->vrf, ifp) - if (ifp->info) { - struct pim_interface *pim_ifp = ifp->info; - struct pim_iface_upstream_switch *us; - - for (ALL_LIST_ELEMENTS_RO( - pim_ifp->upstream_switch_list, - node, us)) { - struct pim_rpf rpf; - rpf.source_nexthop.interface = ifp; - rpf.rpf_addr.u.prefix4 = us->address; - pim_joinprune_send(&rpf, us->us); - pim_jp_agg_clear_group(us->us); - } + rpf.source_nexthop.interface = ifp; + rpf.rpf_addr.u.prefix4 = us->address; + pim_joinprune_send(&rpf, us->us); + pim_jp_agg_clear_group(us->us); } - } + } } void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index) @@ -657,53 +629,41 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index) } } -void pim_scan_oil(struct pim_instance *pim_matcher) +void pim_scan_oil(struct pim_instance *pim) { struct listnode *node; struct listnode *nextnode; struct channel_oil *c_oil; ifindex_t ifindex; int vif_index = 0; - struct vrf *vrf; - struct pim_instance *pim; qpim_scan_oil_last = pim_time_monotonic_sec(); ++qpim_scan_oil_events; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - pim = vrf->info; - if (!pim) - continue; - - if (pim_matcher && pim != pim_matcher) - continue; - - for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode, - c_oil)) { - if (c_oil->up - && c_oil->up->rpf.source_nexthop.interface) { - ifindex = c_oil->up->rpf.source_nexthop - .interface->ifindex; - vif_index = pim_if_find_vifindex_by_ifindex( - pim, ifindex); - /* Pass Current selected NH vif index to mroute - * download */ - if (vif_index) - pim_scan_individual_oil(c_oil, - vif_index); - } else - pim_scan_individual_oil(c_oil, 0); - } + for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode, c_oil)) { + if (c_oil->up && c_oil->up->rpf.source_nexthop.interface) { + ifindex = c_oil->up->rpf.source_nexthop + .interface->ifindex; + vif_index = + pim_if_find_vifindex_by_ifindex(pim, ifindex); + /* Pass Current selected NH vif index to mroute + * download */ + if (vif_index) + pim_scan_individual_oil(c_oil, vif_index); + } else + pim_scan_individual_oil(c_oil, 0); } } static int on_rpf_cache_refresh(struct thread *t) { + struct pim_instance *pim = THREAD_ARG(t); + /* update PIM protocol state */ - scan_upstream_rpf_cache(); + scan_upstream_rpf_cache(pim); /* update kernel multicast forwarding cache (MFC) */ - pim_scan_oil(NULL); + pim_scan_oil(pim); qpim_rpf_cache_refresh_last = pim_time_monotonic_sec(); ++qpim_rpf_cache_refresh_events; @@ -713,13 +673,13 @@ static int on_rpf_cache_refresh(struct thread *t) return 0; } -void sched_rpf_cache_refresh(void) +void sched_rpf_cache_refresh(struct pim_instance *pim) { ++qpim_rpf_cache_refresh_requests; pim_rpf_set_refresh_time(); - if (qpim_rpf_cache_refresher) { + if (pim->rpf_cache_refresher) { /* Refresh timer is already running */ return; } @@ -731,9 +691,9 @@ void sched_rpf_cache_refresh(void) qpim_rpf_cache_refresh_delay_msec); } - thread_add_timer_msec(master, on_rpf_cache_refresh, 0, + thread_add_timer_msec(master, on_rpf_cache_refresh, pim, qpim_rpf_cache_refresh_delay_msec, - &qpim_rpf_cache_refresher); + &pim->rpf_cache_refresher); } static void pim_zebra_connected(struct zclient *zclient) diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h index d9b17cb82d..dd8aed0d20 100644 --- a/pimd/pim_zebra.h +++ b/pimd/pim_zebra.h @@ -44,6 +44,6 @@ void igmp_source_forward_reevaluate_all(void); void pim_forward_start(struct pim_ifchannel *ch); void pim_forward_stop(struct pim_ifchannel *ch, bool install_it); -void sched_rpf_cache_refresh(void); +void sched_rpf_cache_refresh(struct pim_instance *pim); struct zclient *pim_zebra_zclient_get(void); #endif /* PIM_ZEBRA_H */ diff --git a/pimd/pimd.c b/pimd/pimd.c index 52e0920f1f..0532ce873a 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -52,7 +52,6 @@ int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */ struct pim_assert_metric qpim_infinite_assert_metric; long qpim_rpf_cache_refresh_delay_msec = 50; -struct thread *qpim_rpf_cache_refresher = NULL; int64_t qpim_rpf_cache_refresh_requests = 0; int64_t qpim_rpf_cache_refresh_events = 0; int64_t qpim_rpf_cache_refresh_last = 0; diff --git a/pimd/pimd.h b/pimd/pimd.h index de7f259319..89582b991e 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -140,7 +140,6 @@ struct in_addr qpim_all_pim_routers_addr; int qpim_t_periodic; /* Period between Join/Prune Messages */ struct pim_assert_metric qpim_infinite_assert_metric; long qpim_rpf_cache_refresh_delay_msec; -struct thread *qpim_rpf_cache_refresher; int64_t qpim_rpf_cache_refresh_requests; int64_t qpim_rpf_cache_refresh_events; int64_t qpim_rpf_cache_refresh_last; From 5d59e4084180d87f18fded71d25d96ad4774488d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 17 Mar 2018 21:16:42 -0400 Subject: [PATCH 3/4] pimd: make igmp_source_forward_reevaluate_all vrf aware There is no need to look at all VRF's when we need to reevaluate the source forward since the calling function knows the vrf. Signed-off-by: Donald Sharp --- pimd/pim_ssm.c | 2 +- pimd/pim_zebra.c | 62 +++++++++++++++++++++--------------------------- pimd/pim_zebra.h | 2 +- 3 files changed, 29 insertions(+), 37 deletions(-) diff --git a/pimd/pim_ssm.c b/pimd/pim_ssm.c index 71bb6f2abd..d35f5cff7e 100644 --- a/pimd/pim_ssm.c +++ b/pimd/pim_ssm.c @@ -48,7 +48,7 @@ static void pim_ssm_range_reevaluate(struct pim_instance *pim) * disappear in time for SSM groups. */ pim_upstream_register_reevaluate(pim); - igmp_source_forward_reevaluate_all(); + igmp_source_forward_reevaluate_all(pim); } void pim_ssm_prefix_list_update(struct pim_instance *pim, diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index ecb97e8e44..ef9d9068f9 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -824,48 +824,40 @@ static void igmp_source_forward_reevaluate_one(struct pim_instance *pim, } } -void igmp_source_forward_reevaluate_all(void) +void igmp_source_forward_reevaluate_all(struct pim_instance *pim) { struct interface *ifp; - struct vrf *vrf; - struct pim_instance *pim; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - pim = vrf->info; - if (!pim) + FOR_ALL_INTERFACES (pim->vrf, ifp) { + struct pim_interface *pim_ifp = ifp->info; + struct listnode *sock_node; + struct igmp_sock *igmp; + + if (!pim_ifp) continue; - FOR_ALL_INTERFACES (pim->vrf, ifp) { - struct pim_interface *pim_ifp = ifp->info; - struct listnode *sock_node; - struct igmp_sock *igmp; + /* scan igmp sockets */ + for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, sock_node, + igmp)) { + struct listnode *grpnode; + struct igmp_group *grp; - if (!pim_ifp) - continue; + /* scan igmp groups */ + for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, + grpnode, grp)) { + struct listnode *srcnode; + struct igmp_source *src; - /* scan igmp sockets */ - for (ALL_LIST_ELEMENTS_RO(pim_ifp->igmp_socket_list, - sock_node, igmp)) { - struct listnode *grpnode; - struct igmp_group *grp; - - /* scan igmp groups */ - for (ALL_LIST_ELEMENTS_RO(igmp->igmp_group_list, - grpnode, grp)) { - struct listnode *srcnode; - struct igmp_source *src; - - /* scan group sources */ - for (ALL_LIST_ELEMENTS_RO( - grp->group_source_list, - srcnode, src)) { - igmp_source_forward_reevaluate_one( - pim, src); - } /* scan group sources */ - } /* scan igmp groups */ - } /* scan igmp sockets */ - } /* scan interfaces */ - } + /* scan group sources */ + for (ALL_LIST_ELEMENTS_RO( + grp->group_source_list, srcnode, + src)) { + igmp_source_forward_reevaluate_one(pim, + src); + } /* scan group sources */ + } /* scan igmp groups */ + } /* scan igmp sockets */ + } /* scan interfaces */ } void igmp_source_forward_start(struct pim_instance *pim, diff --git a/pimd/pim_zebra.h b/pimd/pim_zebra.h index dd8aed0d20..dd46fd40f9 100644 --- a/pimd/pim_zebra.h +++ b/pimd/pim_zebra.h @@ -39,7 +39,7 @@ void igmp_anysource_forward_stop(struct igmp_group *group); void igmp_source_forward_start(struct pim_instance *pim, struct igmp_source *source); void igmp_source_forward_stop(struct igmp_source *source); -void igmp_source_forward_reevaluate_all(void); +void igmp_source_forward_reevaluate_all(struct pim_instance *pim); void pim_forward_start(struct pim_ifchannel *ch); void pim_forward_stop(struct pim_ifchannel *ch, bool install_it); From bfc920192804b2ce65f8ea11331c2e1cd3568b8b Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sat, 17 Mar 2018 21:34:55 -0400 Subject: [PATCH 4/4] pimd: Move some data tracking variables per VRF There were a few more global variables that needed to be per vrf. So move them over. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 22 +++++++++++----------- pimd/pim_instance.c | 1 + pimd/pim_instance.h | 9 +++++++++ pimd/pim_nht.c | 2 +- pimd/pim_rp.c | 2 +- pimd/pim_rpf.c | 24 +++++++++++------------- pimd/pim_rpf.h | 4 +--- pimd/pim_zebra.c | 12 ++++++------ pimd/pim_zlookup.c | 2 +- pimd/pimd.c | 6 ------ pimd/pimd.h | 6 ------ 11 files changed, 42 insertions(+), 48 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index a8935bf80d..2b21d661c3 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2572,7 +2572,7 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim, char refresh_uptime[10]; pim_time_uptime_begin(refresh_uptime, sizeof(refresh_uptime), now, - qpim_rpf_cache_refresh_last); + pim->rpf_cache_refresh_last); if (json) { json_object_int_add(json, "rpfCacheRefreshDelayMsecs", @@ -2581,15 +2581,15 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim, json, "rpfCacheRefreshTimer", pim_time_timer_remain_msec(pim->rpf_cache_refresher)); json_object_int_add(json, "rpfCacheRefreshRequests", - qpim_rpf_cache_refresh_requests); + pim->rpf_cache_refresh_requests); json_object_int_add(json, "rpfCacheRefreshEvents", - qpim_rpf_cache_refresh_events); + pim->rpf_cache_refresh_events); json_object_string_add(json, "rpfCacheRefreshLast", refresh_uptime); json_object_int_add(json, "nexthopLookups", - qpim_nexthop_lookups); + pim->nexthop_lookups); json_object_int_add(json, "nexthopLookupsAvoided", - nexthop_lookups_avoided); + pim->nexthop_lookups_avoided); } else { vty_out(vty, "RPF Cache Refresh Delay: %ld msecs\n" @@ -2601,10 +2601,10 @@ static void show_rpf_refresh_stats(struct vty *vty, struct pim_instance *pim, "Nexthop Lookups Avoided: %lld\n", qpim_rpf_cache_refresh_delay_msec, pim_time_timer_remain_msec(pim->rpf_cache_refresher), - (long long)qpim_rpf_cache_refresh_requests, - (long long)qpim_rpf_cache_refresh_events, - refresh_uptime, (long long)qpim_nexthop_lookups, - (long long)nexthop_lookups_avoided); + (long long)pim->rpf_cache_refresh_requests, + (long long)pim->rpf_cache_refresh_events, + refresh_uptime, (long long)pim->nexthop_lookups, + (long long)pim->nexthop_lookups_avoided); } } @@ -2616,7 +2616,7 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty, char uptime_mroute_del[10]; pim_time_uptime_begin(uptime_scan_oil, sizeof(uptime_scan_oil), now, - qpim_scan_oil_last); + pim->scan_oil_last); pim_time_uptime_begin(uptime_mroute_add, sizeof(uptime_mroute_add), now, pim->mroute_add_last); pim_time_uptime_begin(uptime_mroute_del, sizeof(uptime_mroute_del), now, @@ -2626,7 +2626,7 @@ static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty, "Scan OIL - Last: %s Events: %lld\n" "MFC Add - Last: %s Events: %lld\n" "MFC Del - Last: %s Events: %lld\n", - uptime_scan_oil, (long long)qpim_scan_oil_events, + uptime_scan_oil, (long long)pim->scan_oil_events, uptime_mroute_add, (long long)pim->mroute_add_events, uptime_mroute_del, (long long)pim->mroute_del_events); } diff --git a/pimd/pim_instance.c b/pimd/pim_instance.c index 60a3308a00..ab4ffc26ae 100644 --- a/pimd/pim_instance.c +++ b/pimd/pim_instance.c @@ -119,6 +119,7 @@ static struct pim_instance *pim_instance_init(struct vrf *vrf) pim_upstream_init(pim); + pim->last_route_change_time = -1; return pim; } diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h index e672c39fdc..75f011513f 100644 --- a/pimd/pim_instance.h +++ b/pimd/pim_instance.h @@ -97,6 +97,15 @@ struct pim_instance { /* If we need to rescan all our upstreams */ struct thread *rpf_cache_refresher; + int64_t rpf_cache_refresh_requests; + int64_t rpf_cache_refresh_events; + int64_t rpf_cache_refresh_last; + int64_t scan_oil_events; + int64_t scan_oil_last; + + int64_t nexthop_lookups; + int64_t nexthop_lookups_avoided; + int64_t last_route_change_time; }; void pim_vrf_init(void); diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 94f19bea77..94cb32bc23 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -759,7 +759,7 @@ int pim_parse_nexthop_update(int command, struct zclient *zclient, pnc->upstream_hash->count, listcount(pnc->rp_list)); } - pim_rpf_set_refresh_time(); + pim_rpf_set_refresh_time(pim); if (listcount(pnc->rp_list)) pim_update_rp_nh(pim, pnc); diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 2395361180..1ad4b33a7e 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -868,7 +868,7 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group) "%s: Nexthop cache not found for RP %s grp %s register with Zebra", __PRETTY_FUNCTION__, buf, buf1); } - pim_rpf_set_refresh_time(); + pim_rpf_set_refresh_time(pim); pim_nexthop_lookup(pim, &rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1); } diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index b5d5f006f2..221c1ee4af 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -37,17 +37,15 @@ #include "pim_nht.h" #include "pim_oil.h" -static long long last_route_change_time = -1; -long long nexthop_lookups_avoided = 0; - static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up); -void pim_rpf_set_refresh_time(void) +void pim_rpf_set_refresh_time(struct pim_instance *pim) { - last_route_change_time = pim_time_monotonic_usec(); + pim->last_route_change_time = pim_time_monotonic_usec(); if (PIM_DEBUG_TRACE) - zlog_debug("%s: New last route change time: %lld", - __PRETTY_FUNCTION__, last_route_change_time); + zlog_debug("%s: vrf(%s) New last route change time: %" PRId64, + __PRETTY_FUNCTION__, pim->vrf->name, + pim->last_route_change_time); } int pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop, @@ -70,7 +68,7 @@ int pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop, return -1; if ((nexthop->last_lookup.s_addr == addr.s_addr) - && (nexthop->last_lookup_time > last_route_change_time)) { + && (nexthop->last_lookup_time > pim->last_route_change_time)) { if (PIM_DEBUG_TRACE) { char addr_str[INET_ADDRSTRLEN]; pim_inet4_dump("", addr, addr_str, @@ -79,12 +77,12 @@ int pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop, pim_addr_dump("", &nexthop->mrib_nexthop_addr, nexthop_str, sizeof(nexthop_str)); zlog_debug( - "%s: Using last lookup for %s at %lld, %lld addr%s", + "%s: Using last lookup for %s at %lld, %" PRId64 " addr%s", __PRETTY_FUNCTION__, addr_str, nexthop->last_lookup_time, - last_route_change_time, nexthop_str); + pim->last_route_change_time, nexthop_str); } - nexthop_lookups_avoided++; + pim->nexthop_lookups_avoided++; return 0; } else { if (PIM_DEBUG_TRACE) { @@ -92,10 +90,10 @@ int pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop, pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); zlog_debug( - "%s: Looking up: %s, last lookup time: %lld, %lld", + "%s: Looking up: %s, last lookup time: %lld, %" PRId64, __PRETTY_FUNCTION__, addr_str, nexthop->last_lookup_time, - last_route_change_time); + pim->last_route_change_time); } } diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h index 86032f1c29..78bbfc7ed9 100644 --- a/pimd/pim_rpf.h +++ b/pimd/pim_rpf.h @@ -56,8 +56,6 @@ enum pim_rpf_result { PIM_RPF_OK = 0, PIM_RPF_CHANGED, PIM_RPF_FAILURE }; struct pim_upstream; -extern long long nexthop_lookups_avoided; - unsigned int pim_rpf_hash_key(void *arg); int pim_rpf_equal(const void *arg1, const void *arg2); @@ -71,5 +69,5 @@ int pim_rpf_addr_is_inaddr_none(struct pim_rpf *rpf); int pim_rpf_addr_is_inaddr_any(struct pim_rpf *rpf); int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2); -void pim_rpf_set_refresh_time(void); +void pim_rpf_set_refresh_time(struct pim_instance *pim); #endif /* PIM_RPF_H */ diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index ef9d9068f9..6cce697202 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -637,8 +637,8 @@ void pim_scan_oil(struct pim_instance *pim) ifindex_t ifindex; int vif_index = 0; - qpim_scan_oil_last = pim_time_monotonic_sec(); - ++qpim_scan_oil_events; + pim->scan_oil_last = pim_time_monotonic_sec(); + ++pim->scan_oil_events; for (ALL_LIST_ELEMENTS(pim->channel_oil_list, node, nextnode, c_oil)) { if (c_oil->up && c_oil->up->rpf.source_nexthop.interface) { @@ -665,8 +665,8 @@ static int on_rpf_cache_refresh(struct thread *t) /* update kernel multicast forwarding cache (MFC) */ pim_scan_oil(pim); - qpim_rpf_cache_refresh_last = pim_time_monotonic_sec(); - ++qpim_rpf_cache_refresh_events; + pim->rpf_cache_refresh_last = pim_time_monotonic_sec(); + ++pim->rpf_cache_refresh_events; // It is called as part of pim_neighbor_add // pim_rp_setup (); @@ -675,9 +675,9 @@ static int on_rpf_cache_refresh(struct thread *t) void sched_rpf_cache_refresh(struct pim_instance *pim) { - ++qpim_rpf_cache_refresh_requests; + ++pim->rpf_cache_refresh_requests; - pim_rpf_set_refresh_time(); + pim_rpf_set_refresh_time(pim); if (pim->rpf_cache_refresher) { /* Refresh timer is already running */ diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 8006148f93..275baedf72 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -352,7 +352,7 @@ int zclient_lookup_nexthop(struct pim_instance *pim, uint32_t route_metric = 0xFFFFFFFF; uint8_t protocol_distance = 0xFF; - qpim_nexthop_lookups++; + pim->nexthop_lookups++; for (lookup = 0; lookup < max_lookup; ++lookup) { int num_ifindex; diff --git a/pimd/pimd.c b/pimd/pimd.c index 0532ce873a..551f6047d7 100644 --- a/pimd/pimd.c +++ b/pimd/pimd.c @@ -52,12 +52,6 @@ int qpim_t_periodic = PIM_DEFAULT_T_PERIODIC; /* Period between Join/Prune Messages */ struct pim_assert_metric qpim_infinite_assert_metric; long qpim_rpf_cache_refresh_delay_msec = 50; -int64_t qpim_rpf_cache_refresh_requests = 0; -int64_t qpim_rpf_cache_refresh_events = 0; -int64_t qpim_rpf_cache_refresh_last = 0; -int64_t qpim_scan_oil_events = 0; -int64_t qpim_scan_oil_last = 0; -int64_t qpim_nexthop_lookups = 0; int qpim_packet_process = PIM_DEFAULT_PACKET_PROCESS; uint8_t qpim_ecmp_enable = 0; uint8_t qpim_ecmp_rebalance_enable = 0; diff --git a/pimd/pimd.h b/pimd/pimd.h index 89582b991e..840e0d7e34 100644 --- a/pimd/pimd.h +++ b/pimd/pimd.h @@ -140,12 +140,6 @@ struct in_addr qpim_all_pim_routers_addr; int qpim_t_periodic; /* Period between Join/Prune Messages */ struct pim_assert_metric qpim_infinite_assert_metric; long qpim_rpf_cache_refresh_delay_msec; -int64_t qpim_rpf_cache_refresh_requests; -int64_t qpim_rpf_cache_refresh_events; -int64_t qpim_rpf_cache_refresh_last; -int64_t qpim_scan_oil_events; -int64_t qpim_scan_oil_last; -int64_t qpim_nexthop_lookups; extern int qpim_packet_process; extern uint8_t qpim_ecmp_enable; extern uint8_t qpim_ecmp_rebalance_enable;