?? route_db.cc
字號:
// such metric, then remove the "set_cost()" statement // below, and add "return true;" at the end of this block. // r->set_cost(RIP_INFINITY); set_deletion_timer(r); updated = true; } // delete_route(r); } } } else { // route from other origin if (!accepted) { delete new_route; return false; } // this is "RIP's decision" -- where one route wins another. // Source-match filtering should go here. bool should_replace = false; do { if (r->cost() > new_route->cost()) { should_replace = true; break; } if (r->cost() < new_route->cost()) break; // XXX: the old route is better // // Same cost routes // if (new_route->cost() == RIP_INFINITY) { // // XXX: Don't update routes if both the old and the new // costs are infinity. // break; } // // If the existing route is showing signs of timing out, it // may be better to switch to an equally-good alternative route // immediately, rather than waiting for the timeout to happen. // The heuristic is: if the route is at least halfway to the // expiration point, switch to the new route // (see RFC 2453 Section 3.9.2 and RFC 2080 Section 2.4.2). // TimeVal expiry_timeval = TimeVal::ZERO(); if (r->origin() != NULL) expiry_timeval = TimeVal(r->origin()->expiry_secs(), 0); if (expiry_timeval == TimeVal::ZERO()) break; // XXX: the old route would never expire TimeVal remain; if (r->timer().time_remaining(remain) != true) break; // XXX: couldn't get the remaining time if (remain < (expiry_timeval / 2)) { should_replace = true; break; } break; } while (false); if (should_replace) { r->set_nexthop(new_route->nexthop()); r->set_ifname(new_route->ifname()); r->set_vifname(new_route->vifname()); r->set_tag(new_route->tag()); r->set_cost(new_route->cost()); r->set_policytags(new_route->policytags()); r->set_origin(o); set_expiry_timer(r); updated = true; } delete new_route; } if (updated) { _uq->push_back(r); } return updated;}template <typename A>voidRouteDB<A>::dump_routes(vector<ConstDBRouteEntry>& routes){ typename RouteContainer::iterator i = _routes.begin(); while (i != _routes.end()) { routes.push_back(i->second); ++i; }}template <typename A>voidRouteDB<A>::flush_routes(){ _uq->flush(); _routes.erase(_routes.begin(), _routes.end());}template <typename A>uint32_tRouteDB<A>::route_count() const{ return _routes.size();}template <typename A>const RouteEntry<A>*RouteDB<A>::find_route(const IPNet<A>& net) const{ typename RouteContainer::const_iterator ri = _routes.find(net); if (ri == _routes.end()) return 0; return ri->second.get();}template <typename A>UpdateQueue<A>&RouteDB<A>::update_queue(){ return *_uq;}template <typename A>const UpdateQueue<A>&RouteDB<A>::update_queue() const{ return *_uq;}template <typename A>typename RouteDB<A>::RouteContainer&RouteDB<A>::routes(){ return _routes;}// ----------------------------------------------------------------------------// RouteWalkertemplate <typename A>const typename RouteWalker<A>::Net RouteWalker<A>::NO_NET(~A::ZERO(), 0);template <typename A>RouteWalker<A>::RouteWalker(RouteDB<A>& rdb) : _route_db(rdb), _state(STATE_RUNNING), _last_visited(NO_NET), _pos(rdb.routes().begin()){}template <typename A>RouteWalker<A>::~RouteWalker(){}template <typename A>const typename RouteWalker<A>::Route*RouteWalker<A>::next_route(){ if (state() != STATE_RUNNING) { XLOG_ERROR("Calling RouteWalker::next_route() whilst not in " "STATE_RUNNING state."); return 0; } if (++_pos == _route_db.routes().end()) { return 0; } return _pos->second.get();}template <typename A>const typename RouteWalker<A>::Route*RouteWalker<A>::current_route(){ if (state() != STATE_RUNNING) { XLOG_ERROR("Calling RouteWalker::next_route() whilst not in " "STATE_RUNNING state."); return 0; } if (_pos == _route_db.routes().end()) { return 0; } return _pos->second.get();}template <typename A>voidRouteWalker<A>::pause(uint32_t pause_ms){ if (state() == STATE_PAUSED) return; _state = STATE_PAUSED; if (_pos == _route_db.routes().end()) { _last_visited = NO_NET; return; } // Check if route has a deletion timer and if so push it's expiry time // back to maximize the chance of the route still being valid when // resume is called. Otherwise we have to do more work to find a good // point to resume from. We're advertising the route at infinity // so advertising it once past it's original expiry is no big deal XorpTimer t = _pos->second->timer(); if (t.scheduled() && _pos->second->cost() == RIP_INFINITY) { TimeVal next_run; _route_db.eventloop().current_time(next_run); next_run += TimeVal(0, 1000 * pause_ms * 2); // factor of 2 == slack if (t.expiry() <= next_run) { t.schedule_at(next_run); _pos->second->set_timer(t); } } _last_visited = _pos->second->net();}template <typename A>voidRouteWalker<A>::resume(){ if (state() != STATE_PAUSED) return; _state = STATE_RUNNING; if (_last_visited == NO_NET) { _pos = _route_db.routes().end(); return; } _pos = _route_db.routes().find(_last_visited); if (_pos == _route_db.routes().end()) { // Node got deleted despite our pushing back it's timer (???) _pos = _route_db.routes().upper_bound(_last_visited); }}template <typename A>voidRouteWalker<A>::reset(){ _state = STATE_RUNNING; _pos = _route_db.routes().begin();}template <typename A>voidRouteDB<A>::push_routes(){ debug_msg("[RIP] Push routes\n"); // // Push the original routes from all peers // for (typename set<Peer<A>* >::iterator i = _peers.begin(); i != _peers.end(); ++i) { Peer<A>* peer = *i; peer->push_routes(); } // XXX may have got RIB route adds because of delete_route // flush is probably not necessary... debug_msg("[RIP] Pushing the RIB routes we have\n"); for (typename RouteContainerNoRef::iterator i = _rib_routes.begin(); i != _rib_routes.end(); ++i) { Route* r = (*i).second; debug_msg("[RIP] Pushing RIB route %s\n", r->net().str().c_str()); update_route(r->net(), r->nexthop(), r->ifname(), r->vifname(), r->cost(), r->tag(), _rib_origin, r->policytags(), true); }}template <typename A>voidRouteDB<A>::add_rib_route(const Net& net, const Addr& nexthop, const string& ifname, const string& vifname, uint32_t cost, uint32_t tag, RouteOrigin* origin, const PolicyTags& policytags){ debug_msg("[RIP] adding RIB route %s\n",net.str().c_str()); _rib_origin = origin; typename RouteContainerNoRef::iterator i = _rib_routes.find(net); if (i != _rib_routes.end()) { Route* prev = (*i).second; delete prev; } // // XXX: We are cheating here NULL origin so we don't get association. // RouteOrigin* no_origin = NULL; Route* r = new Route(net, nexthop, ifname, vifname, cost, no_origin, tag, policytags); _rib_routes[net] = r;}template <typename A>voidRouteDB<A>::delete_rib_route(const Net& net){ debug_msg("[RIP] deleting RIB route %s\n",net.str().c_str()); typename RouteContainerNoRef::iterator i = _rib_routes.find(net); if (i == _rib_routes.end()) return; // XXX: nothing to do Route* r = (*i).second; delete r; _rib_routes.erase(i);}// ----------------------------------------------------------------------------// Instantiations#ifdef INSTANTIATE_IPV4template class RouteDB<IPv4>;template class RouteWalker<IPv4>;#endif#ifdef INSTANTIATE_IPV6template class RouteDB<IPv6>;template class RouteWalker<IPv6>;#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -