void pim_upstream_join_suppress(struct pim_upstream *up, struct in_addr rpf_addr, int holdtime) { long t_joinsuppress_msec; long join_timer_remain_msec; t_joinsuppress_msec = MIN(pim_if_t_suppressed_msec(up->rpf.source_nexthop.interface), 1000 * holdtime); join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer); if (PIM_DEBUG_PIM_TRACE) { char src_str[100]; char grp_str[100]; char rpf_str[100]; pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str)); pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str)); pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str)); zlog_debug("%s %s: detected Join(%s,%s) to RPF'(S,G)=%s: join_timer=%ld msec t_joinsuppress=%ld msec", __FILE__, __PRETTY_FUNCTION__, src_str, grp_str, rpf_str, join_timer_remain_msec, t_joinsuppress_msec); } if (join_timer_remain_msec < t_joinsuppress_msec) { if (PIM_DEBUG_PIM_TRACE) { char src_str[100]; char grp_str[100]; pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str)); pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str)); zlog_debug("%s %s: suppressing Join(S,G)=(%s,%s) for %ld msec", __FILE__, __PRETTY_FUNCTION__, src_str, grp_str, t_joinsuppress_msec); } pim_upstream_join_timer_restart_msec(up, t_joinsuppress_msec); } }
void pim_upstream_join_timer_decrease_to_t_override(const char *debug_label, struct pim_upstream *up, struct in_addr rpf_addr) { long join_timer_remain_msec; int t_override_msec; join_timer_remain_msec = pim_time_timer_remain_msec(up->t_join_timer); t_override_msec = pim_if_t_override_msec(up->rpf.source_nexthop.interface); if (PIM_DEBUG_PIM_TRACE) { char src_str[100]; char grp_str[100]; char rpf_str[100]; pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str)); pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str)); pim_inet4_dump("<rpf?>", rpf_addr, rpf_str, sizeof(rpf_str)); zlog_debug("%s: to RPF'(%s,%s)=%s: join_timer=%ld msec t_override=%d msec", debug_label, src_str, grp_str, rpf_str, join_timer_remain_msec, t_override_msec); } if (join_timer_remain_msec > t_override_msec) { if (PIM_DEBUG_PIM_TRACE) { char src_str[100]; char grp_str[100]; pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str)); pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str)); zlog_debug("%s: decreasing (S,G)=(%s,%s) join timer to t_override=%d msec", debug_label, src_str, grp_str, t_override_msec); } pim_upstream_join_timer_restart_msec(up, t_override_msec); } }
/* RFC 4601: 4.3.1. Sending Hello Messages To allow new or rebooting routers to learn of PIM neighbors quickly, when a Hello message is received from a new neighbor, or a Hello message with a new GenID is received from an existing neighbor, a new Hello message should be sent on this interface after a randomized delay between 0 and Triggered_Hello_Delay. */ void pim_hello_restart_triggered(struct interface *ifp) { struct pim_interface *pim_ifp; int triggered_hello_delay_msec; int random_msec; zassert(ifp); pim_ifp = ifp->info; zassert(pim_ifp); triggered_hello_delay_msec = 1000 * pim_ifp->pim_triggered_hello_delay; if (pim_ifp->t_pim_hello_timer) { long remain_msec = pim_time_timer_remain_msec(pim_ifp->t_pim_hello_timer); if (remain_msec <= triggered_hello_delay_msec) { /* Rescheduling hello would increase the delay, then it's faster to just wait for the scheduled periodic hello. */ return; } THREAD_OFF(pim_ifp->t_pim_hello_timer); pim_ifp->t_pim_hello_timer = 0; } zassert(!pim_ifp->t_pim_hello_timer); random_msec = random() % (triggered_hello_delay_msec + 1); if (PIM_DEBUG_PIM_HELLO) { zlog_debug("Scheduling %d msec triggered hello on interface %s", random_msec, ifp->name); } THREAD_TIMER_MSEC_ON(master, pim_ifp->t_pim_hello_timer, on_pim_hello_send, ifp, random_msec); }