FreeBSD/sbin/routed/rdisc.c
/* Find the best discovered route,
 * and discard stale routers.
 */
Find the best discovered route,
and discard stale routers.
Find the best discovered route and discard stale routers .
static void
rdisc_sort(void)
{
	struct dr *drp, *new_drp;
	struct rt_entry *rt;
	struct rt_spare new;
	struct interface *ifp;
	u_int new_st = 0;
	n_long new_pref = 0;
	new_drp = NULL;
	for (drp = drs; drp < &drs[MAX_ADS]; drp++) {
		if (drp->dr_ts == 0)
			continue;
		ifp = drp->dr_ifp;
		if (drp->dr_ts + drp->dr_life <= now.tv_sec) {
			del_rdisc(drp);
			continue;
		}
		LIM_SEC(rdisc_timer, drp->dr_ts+drp->dr_life+1);
		drp->dr_pref = PREF(drp->dr_recv_pref, ifp);
		if (new_drp == NULL
		    || (!((new_st ^ drp->dr_ifp->int_state) & IS_SICK)
			&& (new_pref < drp->dr_pref
			    || (new_pref == drp->dr_pref
				&& (drp == cur_drp
				    || (new_drp != cur_drp
					&& new_drp->dr_life > drp->dr_life)))))
		    || ((new_st & IS_SICK)
			&& !(drp->dr_ifp->int_state & IS_SICK))) {
			    new_drp = drp;
			    new_st = drp->dr_ifp->int_state;
			    new_pref = drp->dr_pref;
		}
	}
	if (new_drp != cur_drp) {
		rt = rtget(RIP_DEFAULT, 0);
		if (new_drp == NULL) {
			trace_act("turn off Router Discovery client");
			rdisc_ok = 0;
			if (rt != NULL
			    && (rt->rt_state & RS_RDISC)) {
				new = rt->rt_spares[0];
				new.rts_metric = HOPCNT_INFINITY;
				new.rts_time = now.tv_sec - GARBAGE_TIME;
				rtchange(rt, rt->rt_state & ~RS_RDISC,
					 &new, 0);
				rtswitch(rt, 0);
			}
		} else {
			if (cur_drp == NULL) {
				trace_act("turn on Router Discovery client"
					  " using %s via %s",
					  naddr_ntoa(new_drp->dr_gate),
					  new_drp->dr_ifp->int_name);
				rdisc_ok = 1;
			} else {
				trace_act("switch Router Discovery from"
					  " %s via %s to %s via %s",
					  naddr_ntoa(cur_drp->dr_gate),
					  cur_drp->dr_ifp->int_name,
					  naddr_ntoa(new_drp->dr_gate),
					  new_drp->dr_ifp->int_name);
			}
			memset(&new, 0, sizeof(new));
			new.rts_ifp = new_drp->dr_ifp;
			new.rts_gate = new_drp->dr_gate;
			new.rts_router = new_drp->dr_gate;
			new.rts_metric = HOPCNT_INFINITY-1;
			new.rts_time = now.tv_sec;
			if (rt != NULL) {
				rtchange(rt, rt->rt_state | RS_RDISC, &new, 0);
			} else {
				rtadd(RIP_DEFAULT, 0, RS_RDISC, &new);
			}
		}
		cur_drp = new_drp;
	}
	if (!rdisc_ok || rip_interfaces > 1) {
		rip_on(0);
	} else {
		rip_off();
	}
}
static void rdisc_sort ( void ) { struct dr * drp , * new_drp ; struct rt_entry * rt ; struct rt_spare new ; struct interface * ifp ; u_int new_st = 0 ; n_long new_pref = 0 ; new_drp = NULL ; for ( drp = drs ; drp < & drs [ MAX_ADS ] ; drp ++ ) { if ( drp -> dr_ts == 0 ) continue ; ifp = drp -> dr_ifp ; if ( drp -> dr_ts + drp -> dr_life <= now . tv_sec ) { del_rdisc ( drp ) ; continue ; } LIM_SEC ( rdisc_timer , drp -> dr_ts + drp -> dr_life + 1 ) ; drp -> dr_pref = PREF ( drp -> dr_recv_pref , ifp ) ; if ( new_drp == NULL || ( ! ( ( new_st ^ drp -> dr_ifp -> int_state ) & IS_SICK ) && ( new_pref < drp -> dr_pref || ( new_pref == drp -> dr_pref && ( drp == cur_drp || ( new_drp != cur_drp && new_drp -> dr_life > drp -> dr_life ) ) ) ) ) || ( ( new_st & IS_SICK ) && ! ( drp -> dr_ifp -> int_state & IS_SICK ) ) ) { new_drp = drp ; new_st = drp -> dr_ifp -> int_state ; new_pref = drp -> dr_pref ; } } if ( new_drp != cur_drp ) { rt = rtget ( RIP_DEFAULT , 0 ) ; if ( new_drp == NULL ) { trace_act ( " " ) ; rdisc_ok = 0 ; if ( rt != NULL && ( rt -> rt_state & RS_RDISC ) ) { new = rt -> rt_spares [ 0 ] ; new . rts_metric = HOPCNT_INFINITY ; new . rts_time = now . tv_sec - GARBAGE_TIME ; rtchange ( rt , rt -> rt_state & ~ RS_RDISC , & new , 0 ) ; rtswitch ( rt , 0 ) ; } } else { if ( cur_drp == NULL ) { trace_act ( " " " " , naddr_ntoa ( new_drp -> dr_gate ) , new_drp -> dr_ifp -> int_name ) ; rdisc_ok = 1 ; } else { trace_act ( " " " " , naddr_ntoa ( cur_drp -> dr_gate ) , cur_drp -> dr_ifp -> int_name , naddr_ntoa ( new_drp -> dr_gate ) , new_drp -> dr_ifp -> int_name ) ; } memset ( & new , 0 , sizeof ( new ) ) ; new . rts_ifp = new_drp -> dr_ifp ; new . rts_gate = new_drp -> dr_gate ; new . rts_router = new_drp -> dr_gate ; new . rts_metric = HOPCNT_INFINITY - 1 ; new . rts_time = now . tv_sec ; if ( rt != NULL ) { rtchange ( rt , rt -> rt_state | RS_RDISC , & new , 0 ) ; } else { rtadd ( RIP_DEFAULT , 0 , RS_RDISC , & new ) ; } } cur_drp = new_drp ; } if ( ! rdisc_ok || rip_interfaces > 1 ) { rip_on ( 0 ) ; } else { rip_off ( ) ; } }
Find the best discovered route,
 and discard stale routers.
Find the best discovered route and discard stale routers .
/* Find the best discovered route.
	 */ /* Get rid of expired discovered routers.
		 */ /* Update preference with possibly changed interface
		 * metric.
		 */ /* Prefer the current route to prevent thrashing.
		 * Prefer shorter lifetimes to speed the detection of
		 * bad routers.
		 * Avoid sick interfaces.
		 */ /* switch to a better default route
	 */ /* Stop using discovered routes if they are all bad
		 */ /* turn RIP on or off */