📄 rt_table.c
字号:
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 + -