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

📄 rt_table.c

📁 同时支持IPv4和IPv6的BGP协议实现
💻 C
📖 第 1 页 / 共 3 页
字号:
		    if (rte->rt_next == rte) {			    /*			     * There is no other RTE in the list.			     * just free the etnry.			     */			    free(rte);			    return(NULL);		    }		    else {			  rte = base->rt_next; /* advance pointer */			  remque(base);			  free(base);			  return(rte);		    }	    }	    remque(rte);	    free(rte);	    return base;    }    if ((rte = rte->rt_next) == base) {      IFLOG(LOG_ROUTE)	syslog(LOG_DEBUG, "<%s>: Not found", __FUNCTION__);      return base;    }  }  /* NOT REACHED */#undef RTE_LOG_REMOVE  return NULL;}struct rt_entry *aggregatable(struct rt_entry *rte) {  struct rt_entry *agg;  extern struct rt_entry *aggregations;  agg = aggregations;  while(agg) {    if (agg->rt_ripinfo.rip6_plen < rte->rt_ripinfo.rip6_plen &&	IN6_ARE_PRFX_EQUAL(&agg->rt_ripinfo.rip6_dest,			   &rte->rt_ripinfo.rip6_dest,			   agg->rt_ripinfo.rip6_plen))      return agg;    if ((agg = agg->rt_next) == aggregations)      break;  }  return NULL;}struct filtinfo *filter_check(head, addr, plen)	struct filtinfo *head;	/* must not be NULL */	struct in6_addr *addr;	int plen;{	struct filtinfo *filter = head;	while(filter) {		if (filter->filtinfo_plen <= plen &&		    IN6_ARE_PRFX_EQUAL(&filter->filtinfo_addr, addr,				       filter->filtinfo_plen)) {			filter->filtinfo_stat++;			return(filter);		}		if ((filter = filter->filtinfo_next) == head)			break;	}	return(NULL);}struct filtinfo *restrict_check(head, addr, plen)	struct filtinfo *head;	/* must not be NULL */	struct in6_addr *addr;	int plen;{	struct filtinfo *restriction = head;	while(restriction) {		if (restriction->filtinfo_plen <= plen &&		    IN6_ARE_PRFX_EQUAL(&restriction->filtinfo_addr, addr,				       restriction->filtinfo_plen)) {			restriction->filtinfo_stat++;			return(restriction);		}		if ((restriction = restriction->filtinfo_next) == head)			break;	}	return(NULL);}/* * check incoming route. * 1. If we specify to restrict rotes to the default, ignore all *    non default routes. * 2. If we specify the restiction list, ignore the route unless it *    matches at least one entry of the list. * 3. If we filter or generate the default route on the interface, *    ignore incoming defaults. * 4. If we specify the filter list, ignore the route that matches *    at least one entry of the list. * Return value: 1 if filtered. Otherwise return 0 */intinput_filter_check(filters, sitelocal_ok, prefix)	struct filterset *filters;	int sitelocal_ok;	struct ripinfo6 *prefix;{	/* 1st step: restrict to the default */	if ((filters->deffilterflags & DEFAULT_RESTRICTIN) &&	    (prefix->rip6_plen || !IN6_IS_ADDR_UNSPECIFIED(&prefix->rip6_dest))) {		IFLOG(LOG_FILTER)			syslog(LOG_DEBUG,			       "<%s>: route %s/%d was filtered because "			       "it is not the default route",			       __FUNCTION__,			       ip6str(&prefix->rip6_dest, 0),			       prefix->rip6_plen);		filters->input_restrected++;		return(1);	}	/* 2nd step: generic restriction */	if (filters->restrictin) {		struct filtinfo *filter;		if ((filter = restrict_check(filters->restrictin,					     &prefix->rip6_dest, prefix->rip6_plen))		    != NULL) {			IFLOG(LOG_FILTER)				syslog(LOG_DEBUG,				       "<%s>: route %s/%d matched a "				       "restriction(%s/%d)",				       __FUNCTION__,				       ip6str(&prefix->rip6_dest, 0),				       prefix->rip6_plen,				       ip6str(&filter->filtinfo_addr, 0),				       filter->filtinfo_plen);		}		else {			IFLOG(LOG_FILTER)				syslog(LOG_DEBUG,				       "<%s> : route %s/%d was filtered "				       "by restriction",				       __FUNCTION__,				       ip6str(&prefix->rip6_dest, 0),				       prefix->rip6_plen);			filters->input_restrected++; 			return(1);		}	}	/* 3rd step: filter default */	if ((prefix->rip6_plen == 0 &&       /* "default" route */	     IN6_IS_ADDR_UNSPECIFIED(&prefix->rip6_dest)) &&	    (filters->deffilterflags & DEFAULT_FILTERIN)) {		IFLOG(LOG_FILTER)			syslog(LOG_DEBUG, "<%s>: Default route was ignored",			       __FUNCTION__);		return(1);	}		/* 4th step: generic filter */	if (filters->filterin) {		struct filtinfo *filter;		if ((filter = filter_check(filters->filterin,					   &prefix->rip6_dest, prefix->rip6_plen))		    != NULL) {			IFLOG(LOG_FILTER)				syslog(LOG_DEBUG,				       "<%s>: route %s/%d was filtered by "				       "the filter %s/%d",				       __FUNCTION__,				       ip6str(&prefix->rip6_dest, 0),				       prefix->rip6_plen,				       ip6str(&filter->filtinfo_addr, 0),				       filter->filtinfo_plen);			return(1);		}	}	return(0);}/* return 1 if filtered. Otherwise return 0 */intoutput_filter_check(filters, sitelocal_ok, prefix)	struct filterset *filters;	int sitelocal_ok;	struct ripinfo6 *prefix;{	/* 1st step: restrict to the default */	if ((filters->deffilterflags & DEFAULT_RESTRICTOUT) &&	    (prefix->rip6_plen ||	     !IN6_IS_ADDR_UNSPECIFIED(&prefix->rip6_dest))) {		IFLOG(LOG_FILTER)			syslog(LOG_DEBUG,			       "<%s>: route %s/%d was filtered because "			       "it is not the default route",			       __FUNCTION__,			       ip6str(&prefix->rip6_dest, 0),			       prefix->rip6_plen);		filters->output_restrected++;		return(1);	}	/* 2nd step: generic restriction */	if (filters->restrictout) {		struct filtinfo *filter;		if ((filter = restrict_check(filters->restrictout,					    &prefix->rip6_dest,					    prefix->rip6_plen)) != NULL) {			IFLOG(LOG_FILTER)				syslog(LOG_DEBUG,				       "<%s>: route %s/%d matched a "				       "restriction(%s/%d)",				       __FUNCTION__,				       ip6str(&prefix->rip6_dest, 0),				       prefix->rip6_plen,				       ip6str(&filter->filtinfo_addr, 0),				       filter->filtinfo_plen);		}		else {			IFLOG(LOG_FILTER)				syslog(LOG_DEBUG,				       "<%s>: route %s/%d was filtered "				       "by restriction",				       __FUNCTION__,				       ip6str(&prefix->rip6_dest, 0),				       prefix->rip6_plen);			filters->output_restrected++;			return(1);		}	}	/* 3rd step: filter default */	if ((prefix->rip6_plen == 0 &&	     IN6_IS_ADDR_UNSPECIFIED(&prefix->rip6_dest)) &&	    (filters->deffilterflags & DEFAULT_FILTEROUT)) {		IFLOG(LOG_FILTER)			syslog(LOG_DEBUG, "<%s>: Default route was ignored",			       __FUNCTION__);		filters->filtered_outdef++;		return(1);	}	/* 4th step: filter site-local */	if (!sitelocal_ok && IN6_IS_ADDR_SITELOCAL(&prefix->rip6_dest)) {		IFLOG(LOG_FILTER)			syslog(LOG_DEBUG,			       "<%s>: site-local prefix(%s/%d) was ignored",			       __FUNCTION__, ip6str(&prefix->rip6_dest, 0),			       prefix->rip6_plen);		return(1);	}	/* 5th step: generic filter */	if (filters->filterout) {		struct filtinfo *filter;		if ((filter = filter_check(filters->filterout,					  &prefix->rip6_dest,					  prefix->rip6_plen)) != NULL) {			IFLOG(LOG_FILTER)				syslog(LOG_DEBUG,				       "<%s>: route %s/%d was filtered by the "				       "filter %s/%d",				       __FUNCTION__,				       ip6str(&prefix->rip6_dest, 0),				       prefix->rip6_plen,				       ip6str(&filter->filtinfo_addr, 0),				       filter->filtinfo_plen);			return(1);		}	}	return(0);		/* no filter is applied. can be advertised */}voidaggr_ckconf(rte)     struct rt_entry *rte;    /* some specific route */{  struct rt_entry *agg;  if ((agg = aggregatable(rte))) {    agg->rt_aggr.ag_refcnt++;    rte->rt_aggr.ag_agg       = agg;    rte->rt_aggr.ag_flags    |= AGGR_NOADVD;    if (find_rte(rte, agg->rt_aggr.ag_explt))      rte->rt_aggr.ag_flags &= ~AGGR_NOADVD;  }}void aggr_ifinit() {  struct ifinfo        *ife;  extern struct ifinfo *ifentry;  ife = ifentry;  while(ife) {    struct rt_entry *rte;        rte = ife->ifi_rte;    while(rte) {      aggr_ckconf(rte);     /* I/F initially */      if ((rte = rte->rt_next) == ife->ifi_rte)	break;    } /* (rte) */        if ((ife = ife->ifi_next) == ifentry)      break;  } /* (ife) */}voidaggr_flush() {  struct rt_entry *agg;  extern struct rt_entry *aggregations;  agg = aggregations;  while(agg) {    agg->rt_aggr.ag_flags &= ~AGGR_ADVDONE;        if ((agg = agg->rt_next) == aggregations)      return;  }}/* *   aggr_advable() *       1 ... O.K. *       0 ... N.G. */intaggr_advable(agg, rtp)     struct rt_entry *agg;     struct rtproto  *rtp;{  if (!agg || !rtp)    return 0;  if (agg->rt_aggr.ag_refcnt == 0 ||      agg->rt_aggr.ag_flags  &  AGGR_ADVDONE)    return 0;  if (find_rtp(rtp, agg->rt_aggr.ag_rtp))    return 1;  else    return 0;}voidinstall_static(){	struct rt_entry *rte, *nrte;	struct ifinfo *ifp;	for (rte = static_rte_head.rt_next; rte != &static_rte_head;	     rte = nrte) {		nrte = rte->rt_next;		switch(rte->rt_proto.rtp_type) {		case RTPROTO_IF:			ifp = rte->rt_proto.rtp_if;			if (addroute(rte, &rte->rt_gw, ifp)) {				syslog(LOG_ERR,				       "<%s>: failed to install a static route"				       "(%s/%d, gw=%s)",				       __FUNCTION__,				       ip6str(&rte->rt_ripinfo.rip6_dest, 0),				       rte->rt_ripinfo.rip6_plen,				       ip6str(&rte->rt_gw,					      ifp->ifi_ifn->if_index));				fatalx("failed to install a static route");			}			rte->rt_flags |= RTF_UP;			/* chain this rte to as an interface route */			remque(rte);			if (ifp->ifi_rte != NULL)				insque(rte, ifp->ifi_rte);			else {				rte->rt_next = rte->rt_prev = rte;				ifp->ifi_rte = rte;			}			break;		default:			syslog(LOG_ERR,			       "<%s>: unknown origin for static route(%d)",			       __FUNCTION__, rte->rt_proto.rtp_type);			fatalx("install_static: unknown origin for "			       "static route");		}	}}

⌨️ 快捷键说明

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