⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hello.c

📁 unix/linux下的路由守护程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	    if (RT_IFAP(new_rt)		&& !BIT_TEST(RT_IFAP(new_rt)->ifa_state, IFS_UP)) {		/* The interface is down */		goto no_export;	    }	    /* Assign default metric */	    if (new_rt->rt_gwp->gw_proto == RTPROTO_AGGREGATE) {		/* Originate aggregates a metric of one */		result.res_metric = HELLO_HOP;	    } else if (!RT_IFAP(new_rt)		|| BIT_TEST(RT_IFAP(new_rt)->ifa_state, IFS_LOOPBACK)) {		/* Routes via the loopback interface must have an explicit metric */ 		result.res_metric = HELLO_UNREACHABLE;	    } else if (new_rt->rt_gwp->gw_proto == RTPROTO_DIRECT) {		/* Interface routes */		if (BIT_TEST(RT_IFAP(new_rt)->ifa_state, IFS_POINTOPOINT)) {		    /* Add a hop for the P2P link */		    result.res_metric = HELLO_HOP * 2;		} else {		    /* Default to one hop */		    result.res_metric = HELLO_HOP;		}	    } else {		/* Use configured default metric */		result.res_metric = hello_default_metric;	    }			    if (!export(new_rt,			tp->task_rtproto,			hello_export_list,			ifap->ifa_ps[tp->task_rtproto].ips_export,			tlp->target_gwp ? tlp->target_gwp->gw_export : (adv_entry *) 0,			&result)) {		/* Policy prohibits announcement */		goto no_export;	    } else {		/* Add the interface metric */		result.res_metric += ifap->ifa_ps[tp->task_rtproto].ips_metric_out;	    }	    if (result.res_metric < HELLO_UNREACHABLE) {		exportable = TRUE;	    }	    	no_export: ;	}	/* Now that we have determined the exportablility of the new */	/* route we decide what changed need to be made.  The */	/* complexity is required to surpress routing loops both */	/* within HELLO and between HELLO and other protocols. */	/* There are two types of holddowns used, the first one is */	/* called HOLDDOWN and is used when a route goes away or is */	/* overridden by a route that is not suspected to be an echo */	/* of a route we are announcing.  The second is called POISON */	/* and is used when a route is overridden by a route suspected */	/* to be an echo of a route we are announcing. */	if (!tdp) {	    /* New route */	    if (exportable) {		/* and it is exportable */				/* Allocate new entry and fill it in */		TD_ALLOC(tdp);		TD_TSI_SET(tlp, rth, tdp);		tdp->td_rt = new_rt;		rtbit_set(tdp->td_rt, tlp->target_rtbit);		TD_ENQUE(tlp, tdp);		set_metric++;		changes++;	    }	} else if (!new_rt) {	    /* No new route, just an old one */		    if (!BIT_TEST(tdp->td_flags, TDF_POISON|TDF_HOLDDOWN)) {		if (BIT_TEST(tdp->td_rt->rt_state, RTS_DELETE|RTS_HIDDEN)) {		    /* Put into holddown */		    holddown++;		    changed++;		} else {		    /* Poison the old route */		    poison++;		    changed++;		}	    }	} else if (new_rt == tdp->td_rt) {	    /* Something has changed with the route we are announcing */	    if (BIT_TEST(tdp->td_flags, TDF_POISON|TDF_HOLDDOWN)) {		if (exportable) {		    set_metric++;		    changed++;		}	    } else {		if (!exportable) {		    poison++;		    changed++;		} else if (tdp->td_metric != result.res_metric) {		    set_metric++;		    changed++;		}	    }	} else if (!BIT_TEST(new_rt->rt_state, RTS_PENDING)) {	    /* The new route is not from a holddown protocol */	    	    if (exportable		&& (BIT_TEST(new_rt->rt_gwp->gw_flags, GWF_NOHOLD)		    || BIT_TEST(tdp->td_rt->rt_gwp->gw_flags, GWF_NOHOLD))) {		    /* The new route is a ``static'' route or the old route */		    /* is a ``static'' route, override immediately */		    		set_metric++;		changed++;		move_bit++;	    } else if (BIT_TEST(tdp->td_flags, TDF_HOLDDOWN)		&& !BIT_TEST(tdp->td_rt->rt_gwp->gw_flags, GWF_NEEDHOLD)		&& !BIT_TEST(new_rt->rt_gwp->gw_flags, GWF_NEEDHOLD)) {		/* No changes necessary */		changed = move_bit = 0;	    } else if (!BIT_TEST(tdp->td_flags, TDF_POISON|TDF_HOLDDOWN)) {		/* Previously active, has been deleted */		holddown++;		changed++;	    } else {		if (exportable) {		    set_metric++;		    changed++;		} else {		    if (!BIT_TEST(tdp->td_flags, TDF_POISON)) {			poison++;			changed++;		    }		}		move_bit++;	    }	} else {	    /* New route is just better */	    if (BIT_TEST(tdp->td_rt->rt_state, RTS_DELETE|RTS_HIDDEN)) {		if (!BIT_TEST(tdp->td_flags, TDF_HOLDDOWN)) {		    holddown++;		    changed++;		}	    } else {		if (!BIT_TEST(tdp->td_flags, TDF_POISON)) {		    poison++;		    changed++;		}		move_bit++;	    }	}	if ((changed || set_metric)	    && TRACE_TP(tp, TR_POLICY)) {	    if (!logged) {		logged++;		trace_only_tp(tp,			      TRC_NL_BEFORE,			      ("hello_policy: Policy for target %A",			       *tlp->target_dst));	    }	    tracef("\t%A/%A ",		   rth->rth_dest,		   rth->rth_dest_mask);	}	if (set_metric) {	    target_set_metric(tdp, result.res_metric);	    trace_tp(tp,		     TR_POLICY,		     0,		     ("metric %u",		      tdp->td_metric));	} else if (holddown) {	    target_set_holddown(tdp, HELLO_HOLDCOUNT);	    trace_tp(tp,		     TR_POLICY,		     0,		     ("starting holddown"));	} else if (poison) {	    target_set_poison(tdp, HELLO_HOLDCOUNT);	    trace_tp(tp,		     TR_POLICY,		     0,		     ("starting poison"));	} else if (TRACE_TP(tp, TR_POLICY)) {	    trace_clear();	}		if (changed) {	    /* Changed entries need to be at the head of the queue to */	    /* make triggered updates quick */	    TD_DEQUE(tdp);	    TD_ENQUE(tlp, tdp);	    changes++;	}	if (move_bit) {	    /* Move lock to new route */	    rtbit_set(new_rt, tlp->target_rtbit);	    (void) rtbit_reset(tdp->td_rt, tlp->target_rtbit);	    tdp->td_rt = new_rt;	}    } RT_LIST_END(rth, change_list, rt_head) ;    return changes;}/* *	Process changes in the routing table. */static voidhello_flash __PF2(tp, task *,		  change_list, rt_list *){    int changes = 0;    target *tlp;    rt_open(tp);        /* Re-evaluate policy */    TARGET_LIST(tlp, &hello_targets) {	if (BIT_TEST(tlp->target_flags, TARGETF_SUPPLY)) {	    changes += hello_policy(tp, tlp, change_list);	}    } TARGET_LIST_END(tlp, &hello_targets) ;        /* Close the table */    rt_close(tp, (gw_entry *)0, 0, NULL);    if (changes) {	/* Schedule a flash update */	hello_need_flash(tp);    }}/* *	Re-evaluate routing table */static voidhello_newpolicy __PF2(tp, task *,		    change_list, rt_list *){    /* Indicate reconfig done */    BIT_RESET(hello_flags, HELLOF_RECONFIG);    /* And evaluate policy */    hello_flash(tp, change_list);}/* *  Age out HELLO routes */static voidhello_age __PF2(tip, task_timer *,		interval, time_t){    time_t expire_to = time_sec - HELLO_T_EXPIRE;    time_t nexttime = time_sec + 1;    if (expire_to > 0) {	gw_entry *gwp;	rt_open(tip->task_timer_task);    	GW_LIST(hello_gw_list, gwp) {	    rt_entry *rt;	    if (!gwp->gw_n_routes) {		/* No routes for this gateway */		if (!gwp->gw_import		    && !gwp->gw_export		    && !BIT_TEST(gwp->gw_flags, GWF_SOURCE|GWF_TRUSTED)) {		    /* No routes, delete this gateway */		    /* XXX */		}		continue;	    }	    /* Age any routes for this gateway */	    RTQ_LIST(&gwp->gw_rtq, rt) {		if (rt->rt_time <= expire_to) {		    /* This route has expired */				    rt_delete(rt);		} else {		    /* This is the next route to expire */		    if (rt->rt_time < nexttime) {			nexttime = rt->rt_time;		    }		    break;		}	    } RTQ_LIST_END(&gwp->gw_rtq, rt) ;	} GW_LIST_END(hello_gw_list, gwp) ;	rt_close(tip->task_timer_task, (gw_entry *) 0, 0, NULL);    }    if (nexttime > time_sec) {	/* No routes to expire */	nexttime = time_sec;    }    task_timer_set(tip, (time_t) 0, nexttime + HELLO_T_EXPIRE - time_sec);}/* *	Initialize static variables */voidhello_var_init __PF0(void){    hello_flags = HELLOF_CHOOSE;    hello_default_metric = HELLO_UNREACHABLE;    hello_preference = RTPREF_HELLO;}/* *	Cleanup before re-init *//*ARGSUSED*/static voidhello_cleanup __PF1(tp, task *){    adv_cleanup(RTPROTO_HELLO,		&hello_n_trusted,		&hello_n_source,		hello_gw_list,		&hello_int_policy,		&hello_import_list,		&hello_export_list);    if (tp) {	trace_freeup(tp->task_trace);    }    trace_freeup(hello_trace_options);}static voidhello_tsi_dump __PF4(fp, FILE *,		     rth, rt_head *,		     data, void_t,		     pfx, const char *){    target *tlp = (target *) data;    td_entry *tdp;    TD_TSI_GET(tlp, rth, tdp);    if (tdp) {	if (BIT_TEST(tdp->td_flags, TDF_HOLDDOWN|TDF_POISON)) {	    (void) fprintf(fp,			   "%sHELLO %A <%s> remaining %#T\n",			   pfx,			   *tlp->target_dst,			   trace_bits(target_entry_bits, tdp->td_flags),			   tdp->td_metric * HELLO_T_UPDATE);	} else {	    (void) fprintf(fp,			   "%sHELLO %A <%s> metric %u\n",			   pfx,			   *tlp->target_dst,			   trace_bits(target_entry_bits, tdp->td_flags),			   tdp->td_metric);	}    }        return;}/* *	Update the target list */static voidhello_target_list __PF1(jp, task_job *){    register task *tp = jp->task_job_task;    int targets;    flag_t target_flags = 0;    static int n_targets, n_source;    /* If broadcast/nobroadcast not specified, figure out if we */    /* need to broadcast packets */    if (BIT_TEST(hello_flags, HELLOF_CHOOSE)) {	if (if_n_addr[AF_INET].up > 1	    && inet_ipforwarding) {	    BIT_SET(hello_flags, HELLOF_BROADCAST);	} else {	    BIT_RESET(hello_flags, HELLOF_BROADCAST);	}    }    if (!hello_timer_age) {	/* Create route age timer */	hello_timer_age = task_timer_create(tp,					    "Age",					    (flag_t) 0,					    (time_t) 0,					    HELLO_T_EXPIRE,					    hello_age,					    (void_t) 0);    }    if (BIT_TEST(hello_flags, HELLOF_SOURCE|HELLOF_BROADCAST)) {	/* We are supplying updates */	/* Gateways do not listen to redirects */	redirect_disable(tp->task_rtproto);	/* Make sure the timers are active */	if (!hello_timer_update) {	    /* Create the update timer */	    hello_timer_update = task_timer_create(tp,						   "Update",						   0,						   (time_t) HELLO_T_UPDATE,						   (time_t) HELLO_T_MAX,						   hello_job,						   (void_t) 0);	}	if (!hello_timer_flash) {	    /* Create flash update timer */	    hello_timer_flash = task_timer_create(tp,						  "Flash",						  (flag_t) 0,						  (time_t) HELLO_T_FLASH,						  (time_t) HELLO_T_MAX,						  hello_do_flash,						  (void_t) 0);	}    } else {	/* We are just listening */	/* Hosts do listen to redirects */	redirect_enable(tp->task_rtproto);	/* Make sure the timers do not exist */	if (hello_timer_update) {	    task_timer_delete(hello_timer_update);	    hello_timer_update = (task_timer *) 0;	}	if (hello_timer_flash) {	    task_timer_delete(hello_timer_flash);	    hello_timer_flash = (task_timer *) 0;	}    }    /* Set flags for target list build */    if (BIT_TEST(hello_flags, HELLOF_BROADCAST)) {	BIT_SET(target_flags, TARGETF_BROADCAST);    }    if (BIT_TEST(hello_flags, HELLOF_SOURCE)) {	BIT_SET(target_flags, TARGETF_SOURCE);    }    /* Build or update target list */    targets = target_build(tp,			   &hello_targets,			   hello_gw_list,			   target_flags,			   hello_tsi_dump);    /* Allocate the send and receive buffers */    {	mtu_t mtu_max = 0;	target *tlp;		TARGET_LIST(tlp, &hello_targets) {	    if (tlp->target_ifap->ifa_mtu > mtu_max) {		mtu_max = tlp->target_ifap->ifa_mtu;	    }	} TARGET_LIST_END(tlp, &hello_targets) ;	task_alloc_send(tp, (size_t) mtu_max);	task_alloc_recv(tp, (size_t) mtu_max + IP_MAXHDRLEN);    }    /* Evaluate policy for new targets */    {	int changes = 0;	int have_list = 0;	rt_list *rthl = (rt_list *) 0;	target *tlp;	rt_open(tp);		TARGET_LIST(tlp, &hello_targets) {	    if (BIT_TEST(tlp->target_flags, TARGETF_BROADCAST)) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -