routingtable.hxx

Go to the documentation of this file.
00001 // Copyright (C) 2003-2006 Laboratoire de Recherche en Informatique
00002 
00003 // This file is part of Qolyester.
00004 
00005 // Qolyester is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 
00010 // Qolyester is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018 // Boston, MA  02110-1301, USA.
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     // Route calculate and flush routine.
00044     // FIXME: mess left here.
00045     // FIXME: include multiple interface definitions inside the graph
00046     // and don't bother with them at this point.
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       // Populate the local route set.
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       // Apply Dijkstra to populate the remote route set.
00106       alg::dijkstra(remote_rs, local_map);
00107 
00108 # ifdef QOLYESTER_ENABLE_MID
00109       // Complete the sets with multiple interface information.
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           // node in 1-hop
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       // Add routes to non-OLSR networks.
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       // Flush the changes into the system.
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         // Remove old remote routes
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         // Remove old local routes
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         // Add new local routes
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         // Add new remote routes
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   } // namespace alg
00251 
00252 } // namespace olsr
00253 
00254 #endif // !QOLYESTER_DAEMON_ALG_ROUTINGTABLE_HXX

Generated on Mon Sep 4 00:02:16 2006 for Qolyester daemon by  doxygen 1.4.6