From e71bf8f7bd5457e62fed234fcd9d908d4d614906 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 27 Oct 2016 11:54:55 -0400 Subject: [PATCH] pimd: Add basic nexthop lookup cached information. Cache the last time we looked up the nexthop for this particular address. Store time to usec accuracy. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 7 +++++-- pimd/pim_rpf.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++-- pimd/pim_rpf.h | 6 ++++++ pimd/pim_zebra.c | 2 ++ 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 54750d475c..d11c2f21f4 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -1853,6 +1853,7 @@ static void show_rpf_refresh_stats(struct vty *vty, time_t now, json_object *jso json_object_int_add(json, "rpfCacheRefreshEvents", qpim_rpf_cache_refresh_events); json_object_string_add(json, "rpfCacheRefreshLast", refresh_uptime); json_object_int_add(json, "nexthopLookups", qpim_nexthop_lookups); + json_object_int_add(json, "nexthopLookupsAvoided", nexthop_lookups_avoided); } else { vty_out(vty, "RPF Cache Refresh Delay: %ld msecs%s" @@ -1860,13 +1861,15 @@ static void show_rpf_refresh_stats(struct vty *vty, time_t now, json_object *jso "RPF Cache Refresh Requests: %lld%s" "RPF Cache Refresh Events: %lld%s" "RPF Cache Refresh Last: %s%s" - "Nexthop Lookups: %lld%s", + "Nexthop Lookups: %lld%s" + "Nexthop Lookups Avoided: %lld%s", qpim_rpf_cache_refresh_delay_msec, VTY_NEWLINE, pim_time_timer_remain_msec(qpim_rpf_cache_refresher), VTY_NEWLINE, (long long)qpim_rpf_cache_refresh_requests, VTY_NEWLINE, (long long)qpim_rpf_cache_refresh_events, VTY_NEWLINE, refresh_uptime, VTY_NEWLINE, - (long long) qpim_nexthop_lookups, VTY_NEWLINE); + (long long) qpim_nexthop_lookups, VTY_NEWLINE, + (long long)nexthop_lookups_avoided, VTY_NEWLINE); } } diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index d32d65fd4c..2b16529627 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -34,9 +34,22 @@ #include "pim_iface.h" #include "pim_zlookup.h" #include "pim_ifchannel.h" +#include "pim_time.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) +{ + 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); +} + int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed) { struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM]; @@ -46,6 +59,36 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int nei int found = 0; int i = 0; + if ((nexthop->last_lookup.s_addr == addr.s_addr) && + (nexthop->last_lookup_time > last_route_change_time)) + { + if (PIM_DEBUG_TRACE) + { + char addr_str[INET_ADDRSTRLEN]; + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_debug ("%s: Using last lookup for %s at %lld, %lld", + __PRETTY_FUNCTION__, + addr_str, + nexthop->last_lookup_time, + last_route_change_time); + } + nexthop_lookups_avoided++; + return 0; + } + else + { + if (PIM_DEBUG_TRACE) + { + char addr_str[INET_ADDRSTRLEN]; + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_debug ("%s: Looking up: %s, last lookup time: %lld, %lld", + __PRETTY_FUNCTION__, + addr_str, + nexthop->last_lookup_time, + last_route_change_time); + } + } + memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * MULTIPATH_NUM); num_ifindex = zclient_lookup_nexthop(nexthop_tab, MULTIPATH_NUM, @@ -124,11 +167,16 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int nei nexthop->mrib_nexthop_addr = nexthop_tab[0].nexthop_addr; nexthop->mrib_metric_preference = nexthop_tab[0].protocol_distance; nexthop->mrib_route_metric = nexthop_tab[0].route_metric; - + nexthop->last_lookup = addr; + nexthop->last_lookup_time = pim_time_monotonic_usec(); return 0; } else - return -1; + { + nexthop->last_lookup = addr; + nexthop->last_lookup_time = pim_time_monotonic_usec(); + return -1; + } } static int nexthop_mismatch(const struct pim_nexthop *nh1, diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h index b93c934116..b267a9b6fa 100644 --- a/pimd/pim_rpf.h +++ b/pimd/pim_rpf.h @@ -40,6 +40,8 @@ units applicable to the unicast routing protocol used. */ struct pim_nexthop { + struct in_addr last_lookup; + long long last_lookup_time; struct interface *interface; /* RPF_interface(S) */ struct prefix mrib_nexthop_addr; /* MRIB.next_hop(S) */ uint32_t mrib_metric_preference; /* MRIB.pref(S) */ @@ -59,9 +61,13 @@ enum pim_rpf_result { struct pim_upstream; +extern long long nexthop_lookups_avoided; + int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed); enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_rpf_addr); int pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf); int pim_rpf_addr_is_inaddr_any (struct pim_rpf *rpf); + +void pim_rpf_set_refresh_time (void); #endif /* PIM_RPF_H */ diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index eac618b438..e2a71c6e7f 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -550,6 +550,8 @@ static void sched_rpf_cache_refresh() { ++qpim_rpf_cache_refresh_requests; + pim_rpf_set_refresh_time (); + if (qpim_rpf_cache_refresher) { /* Refresh timer is already running */ return; -- 2.39.5