00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QOLYESTER_DAEMON_ALG_ROUTINGTABLE_HXX
00020 # define QOLYESTER_DAEMON_ALG_ROUTINGTABLE_HXX 1
00021
00022 # include "alg/dijkstra.hh"
00023 # include "set/hna.hh"
00024 # include "set/mid.hh"
00025 # include "set/routes.hh"
00026 # include "set/neighbors.hh"
00027 # include "sys/routing.hh"
00028
00029 # include "routingtable.hh"
00030
00031 namespace olsr {
00032
00033 extern hnaset_t hna_set;
00034 extern midset_t mid_set;
00035 extern lrouteset_t lroute_set;
00036 extern rrouteset_t rroute_set;
00037
00038 namespace alg {
00039
00040
00041
00042
00043
00044 void compute_routes()
00045 {
00046 debug << "CALCULATING ROUTING TABLE" << std::endl;
00047
00048 using net::LocalRoute;
00049 using net::RemoteRoute;
00050
00051 lrouteset_t local_rs;
00052 rrouteset_t remote_rs;
00053
00054 std::set<address_t> local_nodes;
00055
00056 typedef std::map<address_t, address_t> localmap_t;
00057 localmap_t local_map;
00058
00059
00060
00061
00062 for (cproxy_t::sym_neighborset_t::iterator n =
00063 cproxy.sym_neighborset().begin();
00064 n != cproxy.sym_neighborset().end(); ++n) {
00065 local_nodes.insert(n->main_addr());
00066 local_map.insert(localmap_t::value_type(n->main_addr(),
00067 n->linkset().begin()->remote_addr()));
00068 bool found = false;
00069 address_t remote_addr;
00070 for (set::Neighbor::linkset_t::iterator l = n->linkset().begin();
00071 l != n->linkset().end(); ++l) {
00072 assert(l->is_valid());
00073
00074 # ifdef QOLYESTER_ENABLE_MID
00075 local_rs.insert(LocalRoute(l->remote_addr(), 8 * ADDRESS_SIZE,
00076 iface_set[l->local_addr()].info()));
00077 # else // ! QOLYESTER_ENABLE_MID
00078 local_rs.insert(LocalRoute(l->remote_addr(), 8 * ADDRESS_SIZE,
00079 this_interface.info()));
00080 # endif
00081
00082 if (!found) {
00083 found = true;
00084 remote_addr = l->remote_addr();
00085 }
00086 }
00087 assert(found);
00088 if (!local_rs[LocalRoute::make_key(n->main_addr(), 8 * ADDRESS_SIZE)])
00089 remote_rs.insert(RemoteRoute(n->main_addr(), 8 * ADDRESS_SIZE,
00090 remote_addr));
00091 }
00092
00093
00094 alg::dijkstra(remote_rs, local_map);
00095
00096 # ifdef QOLYESTER_ENABLE_MID
00097
00098 for (midset_t::midset_t::iterator i = mid_set.midset().begin();
00099 i != mid_set.midset().end(); ++i) {
00100 lrouteset_t::iterator lr =
00101 local_rs.find(LocalRoute::make_key(i->main_addr(),
00102 8 * ADDRESS_SIZE));
00103 if (lr != local_rs.end()) {
00104
00105 if (!local_rs[LocalRoute::make_key(i->iface_addr(),
00106 8 * ADDRESS_SIZE)])
00107 remote_rs.insert(RemoteRoute(i->iface_addr(), 8 * ADDRESS_SIZE,
00108 i->main_addr()));
00109 } else {
00110 rrouteset_t::iterator rr =
00111 remote_rs.find(RemoteRoute::make_key(i->main_addr(),
00112 8 * ADDRESS_SIZE));
00113 if (rr != remote_rs.end())
00114 if (!local_rs[LocalRoute::make_key(i->iface_addr(),
00115 8 * ADDRESS_SIZE)])
00116 remote_rs.insert(RemoteRoute(i->iface_addr(), 8 * ADDRESS_SIZE,
00117 rr->next_addr()));
00118 }
00119 }
00120 # endif // ! QOLYESTER_ENABLE_MID
00121
00122 # ifdef QOLYESTER_ENABLE_HNA
00123
00124 for (hnaset_t::hnaset_t::iterator i = hna_set.hnaset().begin();
00125 i != hna_set.hnaset().end(); ++i) {
00126 lrouteset_t::iterator lr =
00127 local_rs.find(LocalRoute::make_key(i->gw_addr(), 8 * ADDRESS_SIZE));
00128 if (lr != local_rs.end())
00129 remote_rs.insert(RemoteRoute(i->net_addr(), i->prefix(),
00130 lr->dest_addr()));
00131 else {
00132 rrouteset_t::iterator rr =
00133 remote_rs.find(RemoteRoute::make_key(i->gw_addr(),
00134 8 * ADDRESS_SIZE));
00135 if (rr != remote_rs.end())
00136 remote_rs.insert(RemoteRoute(i->net_addr(), i->prefix(),
00137 rr->next_addr()));
00138 }
00139 }
00140 # endif // ! QOLYESTER_ENABLE_HNA
00141
00142 # ifdef DEBUG
00143 debug << "Route set change from {\n";
00144 for (lrouteset_t::const_iterator i = lroute_set.begin();
00145 i != lroute_set.end(); ++i) {
00146 debug << " " << i->dest_addr() << "/" << i->prefix() << " : "
00147 << i->interface_info().name() << "\n";
00148 }
00149 for (rrouteset_t::const_iterator i = rroute_set.begin();
00150 i != rroute_set.end(); ++i)
00151 debug << " " << i->dest_addr() << "/" << i->prefix() << " : "
00152 << i->next_addr() << "\n";
00153 debug << "} to {\n";
00154 for (lrouteset_t::const_iterator i = local_rs.begin();
00155 i != local_rs.end(); ++i) {
00156 debug << " " << i->dest_addr() << "/" << i->prefix() << " : "
00157 << i->interface_info().name() << "\n";
00158 }
00159 for (rrouteset_t::const_iterator i = remote_rs.begin();
00160 i != remote_rs.end(); ++i)
00161 debug << " " << i->dest_addr() << "/" << i->prefix() << " : "
00162 << i->next_addr() << "\n";
00163 debug << "}" << std::endl;
00164 # endif // !DEBUG
00165
00166
00167
00168 flush_routes(local_rs, remote_rs);
00169 }
00170
00171 void flush_routes(const lrouteset_t& local_rs,
00172 const rrouteset_t& remote_rs)
00173 {
00174 lrouteset_t addlroutes = local_rs - lroute_set;
00175 rrouteset_t addrroutes = remote_rs - rroute_set;
00176 rrouteset_t delrroutes = rroute_set - remote_rs;
00177 lrouteset_t dellroutes = lroute_set - local_rs;
00178
00179 debug << "Flushing routes {\n";
00180
00181 if (!notables) {
00182 sys::RoutingActions ra;
00183
00184 ra.print_kernel_routes();
00185
00186
00187 for (rrouteset_t::iterator r = delrroutes.begin();
00188 r != delrroutes.end(); ++r) {
00189 debug << " - " << r->dest_addr() << "/" << r->prefix()
00190 << " : " << r->next_addr() << "\n";
00191 ra.remove_remote_route(*r);
00192 }
00193
00194
00195 for (lrouteset_t::iterator r = dellroutes.begin();
00196 r != dellroutes.end(); ++r) {
00197 debug << " - " << r->dest_addr() << "/" << r->prefix()
00198 << " : " << r->interface_info().name() << "\n";
00199 ra.remove_local_route(*r);
00200 }
00201
00202
00203 for (lrouteset_t::iterator r = addlroutes.begin();
00204 r != addlroutes.end(); ++r) {
00205 debug << " + " << r->dest_addr() << "/" << r->prefix()
00206 << " : " << r->interface_info().name() << "\n";
00207 ra.add_local_route(*r);
00208 }
00209
00210
00211 for (rrouteset_t::iterator r = addrroutes.begin();
00212 r != addrroutes.end(); ++r) {
00213 debug << " + " << r->dest_addr() << "/" << r->prefix()
00214 << " : " << r->next_addr() << "\n";
00215 ra.add_remote_route(*r);
00216 }
00217
00218 ra.print_kernel_routes();
00219
00220 }
00221
00222 debug << "}" << std::endl;
00223
00224 rroute_set = remote_rs;
00225 lroute_set = local_rs;
00226 }
00227
00228 void clean_routes()
00229 {
00230 if (!notables) {
00231 sys::RoutingActions ra;
00232 debug << "Removing old routes";
00233 ra.remove_old_routes();
00234 debug << std::endl;
00235 }
00236 }
00237
00238 }
00239
00240 }
00241
00242 #endif // !QOLYESTER_DAEMON_ALG_ROUTINGTABLE_HXX