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"
"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);
}
}
#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];
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, 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, 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,
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,
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) */
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 */
{
++qpim_rpf_cache_refresh_requests;
+ pim_rpf_set_refresh_time ();
+
if (qpim_rpf_cache_refresher) {
/* Refresh timer is already running */
return;