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 if (n->willingness() > WILL_NEVER)
00088 local_map.insert(std::make_pair(l->remote_addr(),
00089 std::make_pair(remote_addr, n)));
00090 }
00091 assert(found);
00092 if (!local_rs[LocalRoute::make_key(n->main_addr(),
00093 8 * ADDRESS_SIZE)]) {
00094 remote_rs.insert(RemoteRoute(n->main_addr(), 8 * ADDRESS_SIZE,
00095 remote_addr));
00096 if (n->willingness() > WILL_NEVER)
00097 local_map.insert(std::make_pair(n->main_addr(),
00098 std::make_pair(remote_addr, n)));
00099 } else if (n->willingness() > WILL_NEVER)
00100 local_map.insert(std::make_pair(n->main_addr(),
00101 std::make_pair(n->main_addr(), n)));
00102
00103 }
00104
00105
00106 alg::dijkstra(remote_rs, local_map);
00107
00108 # ifdef QOLYESTER_ENABLE_MID
00109
00110 for (midset_t::midset_t::iterator i = mid_set.midset().begin();
00111 i != mid_set.midset().end(); ++i) {
00112 lrouteset_t::iterator lr =
00113 local_rs.find(LocalRoute::make_key(i->main_addr(),
00114 8 * ADDRESS_SIZE));
00115 if (lr != local_rs.end()) {
00116
00117 if (!local_rs[LocalRoute::make_key(i->iface_addr(),
00118 8 * ADDRESS_SIZE)])
00119 remote_rs.insert(RemoteRoute(i->iface_addr(), 8 * ADDRESS_SIZE,
00120 i->main_addr()));
00121 } else {
00122 rrouteset_t::iterator rr =
00123 remote_rs.find(RemoteRoute::make_key(i->main_addr(),
00124 8 * ADDRESS_SIZE));
00125 if (rr != remote_rs.end())
00126 if (!local_rs[LocalRoute::make_key(i->iface_addr(),
00127 8 * ADDRESS_SIZE)])
00128 remote_rs.insert(RemoteRoute(i->iface_addr(), 8 * ADDRESS_SIZE,
00129 rr->next_addr()));
00130 }
00131 }
00132 # endif // ! QOLYESTER_ENABLE_MID
00133
00134 # ifdef QOLYESTER_ENABLE_HNA
00135
00136 for (hnaset_t::hnaset_t::iterator i = hna_set.hnaset().begin();
00137 i != hna_set.hnaset().end(); ++i) {
00138 lrouteset_t::iterator lr =
00139 local_rs.find(LocalRoute::make_key(i->gw_addr(), 8 * ADDRESS_SIZE));
00140 if (lr != local_rs.end())
00141 remote_rs.insert(RemoteRoute(i->net_addr(), i->prefix(),
00142 lr->dest_addr()));
00143 else {
00144 rrouteset_t::iterator rr =
00145 remote_rs.find(RemoteRoute::make_key(i->gw_addr(),
00146 8 * ADDRESS_SIZE));
00147 if (rr != remote_rs.end())
00148 remote_rs.insert(RemoteRoute(i->net_addr(), i->prefix(),
00149 rr->next_addr()));
00150 }
00151 }
00152 # endif // ! QOLYESTER_ENABLE_HNA
00153
00154 # ifdef DEBUG
00155 debug << "Route set change from {\n";
00156 for (lrouteset_t::const_iterator i = lroute_set.begin();
00157 i != lroute_set.end(); ++i) {
00158 debug << " " << i->dest_addr() << '/' << i->prefix() << " : "
00159 << i->interface_info().name() << '\n';
00160 }
00161 for (rrouteset_t::const_iterator i = rroute_set.begin();
00162 i != rroute_set.end(); ++i)
00163 debug << " " << i->dest_addr() << '/' << i->prefix() << " : "
00164 << i->next_addr() << '\n';
00165 debug << "} to {\n";
00166 for (lrouteset_t::const_iterator i = local_rs.begin();
00167 i != local_rs.end(); ++i) {
00168 debug << " " << i->dest_addr() << '/' << i->prefix() << " : "
00169 << i->interface_info().name() << '\n';
00170 }
00171 for (rrouteset_t::const_iterator i = remote_rs.begin();
00172 i != remote_rs.end(); ++i)
00173 debug << " " << i->dest_addr() << '/' << i->prefix() << " : "
00174 << i->next_addr() << '\n';
00175 debug << '}' << std::endl;
00176 # endif // !DEBUG
00177
00178
00179
00180 flush_routes(local_rs, remote_rs);
00181 }
00182
00183 void flush_routes(const lrouteset_t& local_rs,
00184 const rrouteset_t& remote_rs)
00185 {
00186 lrouteset_t addlroutes = local_rs - lroute_set;
00187 rrouteset_t addrroutes = remote_rs - rroute_set;
00188 rrouteset_t delrroutes = rroute_set - remote_rs;
00189 lrouteset_t dellroutes = lroute_set - local_rs;
00190
00191 debug << "Flushing routes {\n";
00192
00193 if (!notables) {
00194 sys::RoutingActions ra;
00195
00196 ra.print_kernel_routes();
00197
00198
00199 for (rrouteset_t::iterator r = delrroutes.begin();
00200 r != delrroutes.end(); ++r) {
00201 debug << " - " << r->dest_addr() << '/' << r->prefix()
00202 << " : " << r->next_addr() << '\n';
00203 ra.remove_remote_route(*r);
00204 }
00205
00206
00207 for (lrouteset_t::iterator r = dellroutes.begin();
00208 r != dellroutes.end(); ++r) {
00209 debug << " - " << r->dest_addr() << '/' << r->prefix()
00210 << " : " << r->interface_info().name() << '\n';
00211 ra.remove_local_route(*r);
00212 }
00213
00214
00215 for (lrouteset_t::iterator r = addlroutes.begin();
00216 r != addlroutes.end(); ++r) {
00217 debug << " + " << r->dest_addr() << '/' << r->prefix()
00218 << " : " << r->interface_info().name() << '\n';
00219 ra.add_local_route(*r);
00220 }
00221
00222
00223 for (rrouteset_t::iterator r = addrroutes.begin();
00224 r != addrroutes.end(); ++r) {
00225 debug << " + " << r->dest_addr() << '/' << r->prefix()
00226 << " : " << r->next_addr() << '\n';
00227 ra.add_remote_route(*r);
00228 }
00229
00230 ra.print_kernel_routes();
00231
00232 }
00233
00234 debug << '}' << std::endl;
00235
00236 rroute_set = remote_rs;
00237 lroute_set = local_rs;
00238 }
00239
00240 void clean_routes()
00241 {
00242 if (!notables) {
00243 sys::RoutingActions ra;
00244 debug << "Removing old routes";
00245 ra.remove_old_routes();
00246 debug << std::endl;
00247 }
00248 }
00249
00250 }
00251
00252 }
00253
00254 #endif // !QOLYESTER_DAEMON_ALG_ROUTINGTABLE_HXX