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