📄 linktable.cc
字号:
/* * LinkTable.{cc,hh} -- Routing Table in terms of links * John Bicket * * Copyright (c) 1999-2001 Massachusetts Institute of Technology * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, subject to the conditions * listed in the Click LICENSE file. These conditions include: you must * preserve this copyright notice, and you cannot mention the copyright * holders in advertising related to the Software without their permission. * The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This * notice is a summary of the Click LICENSE file; the license in that file is * legally binding. */#include <click/config.h>#include "linktable.hh"#include <click/ipaddress.hh>#include <click/confparse.hh>#include <click/error.hh>#include <click/glue.hh>#include <elements/wifi/sr/path.hh>#include <click/straccum.hh>CLICK_DECLSLinkTable::LinkTable() : _timer(this){}LinkTable::~LinkTable() {}intLinkTable::initialize (ErrorHandler *) { _timer.initialize(this); _timer.schedule_now(); return 0;}voidLinkTable::run_timer() { clear_stale(); dijkstra(true); dijkstra(false); _timer.schedule_after_ms(5000);}void *LinkTable::cast(const char *n){ if (strcmp(n, "LinkTable") == 0) return (LinkTable *) this; else return 0;}intLinkTable::configure (Vector<String> &conf, ErrorHandler *errh){ int ret; int stale_period = 120; ret = cp_va_parse(conf, this, errh, cpKeywords, "IP", cpIPAddress, "IP address", &_ip, "STALE", cpUnsigned, "Stale info timeout", &stale_period, cpEnd); if (!_ip) return errh->error("IP not specified"); _stale_timeout.tv_sec = stale_period; _stale_timeout.tv_usec = 0; _hosts.insert(_ip, HostInfo(_ip)); return ret;}void LinkTable::take_state(Element *e, ErrorHandler *) { LinkTable *q = (LinkTable *)e->cast("LinkTable"); if (!q) return; _hosts = q->_hosts; _links = q->_links; dijkstra(true); dijkstra(false);}intLinkTable::static_update_link(const String &arg, Element *e, void *, ErrorHandler *errh) { LinkTable *n = (LinkTable *) e; Vector<String> args; IPAddress from; IPAddress to; uint32_t seq; uint32_t age; uint32_t metric; cp_spacevec(arg, args); if (args.size() != 5) { return errh->error("Must have three arguments: currently has %d: %s", args.size(), args[0].cc()); } if (!cp_ip_address(args[0], &from)) { return errh->error("Couldn't read IPAddress out of from"); } if (!cp_ip_address(args[1], &to)) { return errh->error("Couldn't read IPAddress out of to"); } if (!cp_unsigned(args[2], &metric)) { return errh->error("Couldn't read metric"); } if (!cp_unsigned(args[3], &seq)) { return errh->error("Couldn't read seq"); } if (!cp_unsigned(args[4], &age)) { return errh->error("Couldn't read age"); } n->update_link(from, to, seq, age, metric); return 0;}voidLinkTable::clear() { _hosts.clear(); _links.clear();}bool LinkTable::update_link(IPAddress from, IPAddress to, uint32_t seq, uint32_t age, uint32_t metric){ if (!from || !to || !metric) { return false; } if (_stale_timeout.tv_sec < (int) age) { return true; } /* make sure both the hosts exist */ HostInfo *nfrom = _hosts.findp(from); if (!nfrom) { HostInfo foo = HostInfo(from); _hosts.insert(from, foo); nfrom = _hosts.findp(from); } HostInfo *nto = _hosts.findp(to); if (!nto) { _hosts.insert(to, HostInfo(to)); nto = _hosts.findp(to); } assert(nfrom); assert(nto); IPPair p = IPPair(from, to); LinkInfo *lnfo = _links.findp(p); if (!lnfo) { _links.insert(p, LinkInfo(from, to, seq, age, metric)); } else { lnfo->update(seq, age, metric); } return true;}LinkTable::Link LinkTable::random_link(){ int ndx = random() % _links.size(); int current_ndx = 0; for (LTIter iter = _links.begin(); iter; iter++, current_ndx++) { if (current_ndx == ndx) { LinkInfo n = iter.value(); return Link(n._from, n._to, n._seq, n._metric); } } click_chatter("LinkTable %s: random_link overestimated number of elements\n", id().cc()); return Link();}Vector<IPAddress> LinkTable::get_hosts(){ Vector<IPAddress> v; for (HTIter iter = _hosts.begin(); iter; iter++) { HostInfo n = iter.value(); v.push_back(n._ip); } return v;}uint32_t LinkTable::get_host_metric_to_me(IPAddress s){ if (!s) { return 0; } HostInfo *nfo = _hosts.findp(s); if (!nfo) { return 0; } return nfo->_metric_to_me;}uint32_t LinkTable::get_host_metric_from_me(IPAddress s){ if (!s) { return 0; } HostInfo *nfo = _hosts.findp(s); if (!nfo) { return 0; } return nfo->_metric_from_me;}uint32_t LinkTable::get_link_metric(IPAddress from, IPAddress to) { if (!from || !to) { return 0; } if (_blacklist.findp(from) || _blacklist.findp(to)) { return 0; } IPPair p = IPPair(from, to); LinkInfo *nfo = _links.findp(p); if (!nfo) { return 0; } return nfo->_metric;}uint32_t LinkTable::get_link_seq(IPAddress from, IPAddress to) { if (!from || !to) { return 0; } if (_blacklist.findp(from) || _blacklist.findp(to)) { return 0; } IPPair p = IPPair(from, to); LinkInfo *nfo = _links.findp(p); if (!nfo) { return 0; } return nfo->_seq;}uint32_t LinkTable::get_link_age(IPAddress from, IPAddress to) { if (!from || !to) { return 0; } if (_blacklist.findp(from) || _blacklist.findp(to)) { return 0; } IPPair p = IPPair(from, to); LinkInfo *nfo = _links.findp(p); if (!nfo) { return 0; } struct timeval now; click_gettimeofday(&now); return nfo->age();} unsigned LinkTable::get_route_metric(Vector<IPAddress> route) { unsigned metric = 0; for (int i = 0; i < route.size() - 1; i++) { unsigned m = get_link_metric(route[i], route[i+1]); if (m == 0) { return 0; } metric += m; } return metric; }String LinkTable::routes_to_string(Vector< Vector<IPAddress> > routes) { StringAccum sa; for (int x = 0; x < routes.size(); x++) { Vector <IPAddress> r = routes[x]; for (int i = 0; i < r.size(); i++) { if (i != 0) { sa << " "; } sa << r[i] << " "; if (i != r.size()-1) { sa << get_link_metric(r[i], r[i+1]); } } if (r.size() > 0) { sa << "\n"; } } return sa.take_string();}boolLinkTable::valid_route(Vector<IPAddress> route) { if (route.size() < 1) { return false; } /* ensure the metrics are all valid */ unsigned metric = get_route_metric(route); if (metric == 0 || metric >= 777777){ return false; } /* ensure that a node appears no more than once */ for (int x = 0; x < route.size(); x++) { for (int y = x + 1; y < route.size(); y++) { if (route[x] == route[y]) { return false; } } } return true;}Vector<IPAddress> LinkTable::best_route(IPAddress dst, bool from_me){ Vector<IPAddress> reverse_route; Vector<IPAddress> route; if (!dst) { return route; } HostInfo *nfo = _hosts.findp(dst); if (from_me) { while (nfo && nfo->_metric_from_me != 0) { reverse_route.push_back(nfo->_ip); nfo = _hosts.findp(nfo->_prev_from_me); } if (nfo && nfo->_metric_from_me == 0) { reverse_route.push_back(nfo->_ip); } } else { while (nfo && nfo->_metric_to_me != 0) { reverse_route.push_back(nfo->_ip); nfo = _hosts.findp(nfo->_prev_to_me); } if (nfo && nfo->_metric_to_me == 0) { reverse_route.push_back(nfo->_ip); } } if (from_me) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -