Home | History | Annotate | Download | only in shill
      1 //
      2 // Copyright (C) 2012 The Android Open Source Project
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 //
     16 
     17 #ifndef SHILL_ROUTING_TABLE_H_
     18 #define SHILL_ROUTING_TABLE_H_
     19 
     20 #include <deque>
     21 #include <memory>
     22 #include <string>
     23 #include <unordered_map>
     24 #include <vector>
     25 
     26 #include <base/callback.h>
     27 #include <base/lazy_instance.h>
     28 #include <base/memory/ref_counted.h>
     29 
     30 #include "shill/net/ip_address.h"
     31 #include "shill/net/rtnl_message.h"
     32 #include "shill/refptr_types.h"
     33 
     34 namespace shill {
     35 
     36 class RTNLHandler;
     37 class RTNLListener;
     38 struct RoutingTableEntry;
     39 
     40 // This singleton maintains an in-process copy of the routing table on
     41 // a per-interface basis.  It offers the ability for other modules to
     42 // make modifications to the routing table, centered around setting the
     43 // default route for an interface or modifying its metric (priority).
     44 class RoutingTable {
     45  public:
     46   typedef std::vector<RoutingTableEntry> TableEntryVector;
     47   typedef std::unordered_map<int, TableEntryVector> Tables;
     48 
     49   struct Query {
     50     // Callback::Run(interface_index, entry)
     51     typedef base::Callback<void(int, const RoutingTableEntry&)> Callback;
     52 
     53     Query() : sequence(0), tag(0), table_id(0) {}
     54     Query(uint32_t sequence_in,
     55           int tag_in,
     56           Callback callback_in,
     57           uint8_t table_id_in)
     58         : sequence(sequence_in),
     59           tag(tag_in),
     60           callback(callback_in),
     61           table_id(table_id_in) {}
     62 
     63     uint32_t sequence;
     64     int tag;
     65     Callback callback;
     66     uint8_t table_id;
     67   };
     68 
     69   virtual ~RoutingTable();
     70 
     71   static RoutingTable* GetInstance();
     72 
     73   virtual void Start();
     74   virtual void Stop();
     75 
     76   // Add an entry to the routing table.
     77   virtual bool AddRoute(int interface_index, const RoutingTableEntry& entry);
     78 
     79   // Get the default route associated with an interface of a given addr family.
     80   // The route is copied into |*entry|.
     81   virtual bool GetDefaultRoute(int interface_index,
     82                                IPAddress::Family family,
     83                                RoutingTableEntry* entry);
     84 
     85   // Set the default route for an interface with index |interface_index|,
     86   // given the IPAddress of the gateway |gateway_address| and priority
     87   // |metric|.
     88   virtual bool SetDefaultRoute(int interface_index,
     89                                const IPAddress& gateway_address,
     90                                uint32_t metric,
     91                                uint8_t table_id);
     92 
     93   // Configure routing table entries from the "routes" portion of |ipconfig|.
     94   // Returns true if all routes were installed successfully, false otherwise.
     95   virtual bool ConfigureRoutes(int interface_index,
     96                                const IPConfigRefPtr& ipconfig,
     97                                uint32_t metric,
     98                                uint8_t table_id);
     99 
    100   // Create a blackhole route for a given IP family.  Returns true
    101   // on successfully sending the route request, false otherwise.
    102   virtual bool CreateBlackholeRoute(int interface_index,
    103                                     IPAddress::Family family,
    104                                     uint32_t metric,
    105                                     uint8_t table_id);
    106 
    107   // Create a route to a link-attached remote host.  |remote_address|
    108   // must be directly reachable from |local_address|.  Returns true
    109   // on successfully sending the route request, false otherwise.
    110   virtual bool CreateLinkRoute(int interface_index,
    111                                const IPAddress& local_address,
    112                                const IPAddress& remote_address,
    113                                uint8_t table_id);
    114 
    115   // Remove routes associated with interface.
    116   // Route entries are immediately purged from our copy of the routing table.
    117   virtual void FlushRoutes(int interface_index);
    118 
    119   // Iterate over all routing tables removing routes tagged with |tag|.
    120   // Route entries are immediately purged from our copy of the routing table.
    121   virtual void FlushRoutesWithTag(int tag);
    122 
    123   // Flush the routing cache for all interfaces.
    124   virtual bool FlushCache();
    125 
    126   // Reset local state for this interface.
    127   virtual void ResetTable(int interface_index);
    128 
    129   // Set the metric (priority) on existing default routes for an interface.
    130   virtual void SetDefaultMetric(int interface_index, uint32_t metric);
    131 
    132   // Get the default route to |destination| through |interface_index| and create
    133   // a host route to that destination.  When creating the route, tag our local
    134   // entry with |tag|, so we can remove it later.  Connections use their
    135   // interface index as the tag, so that as they are destroyed, they can remove
    136   // all their dependent routes.  If |callback| is not null, it will be invoked
    137   // when the request-route response is received and the add-route request has
    138   // been sent successfully.
    139   virtual bool RequestRouteToHost(const IPAddress& destination,
    140                                   int interface_index,
    141                                   int tag,
    142                                   const Query::Callback& callback,
    143                                   uint8_t table_id);
    144 
    145  protected:
    146   RoutingTable();
    147 
    148  private:
    149   friend struct base::DefaultLazyInstanceTraits<RoutingTable>;
    150   friend class RoutingTableTest;
    151 
    152   static bool ParseRoutingTableMessage(const RTNLMessage& message,
    153                                        int* interface_index,
    154                                        RoutingTableEntry* entry);
    155   void RouteMsgHandler(const RTNLMessage& msg);
    156   bool ApplyRoute(uint32_t interface_index,
    157                   const RoutingTableEntry& entry,
    158                   RTNLMessage::Mode mode,
    159                   unsigned int flags);
    160   // Get the default route associated with an interface of a given addr family.
    161   // A pointer to the route is placed in |*entry|.
    162   virtual bool GetDefaultRouteInternal(int interface_index,
    163                                IPAddress::Family family,
    164                                RoutingTableEntry** entry);
    165 
    166   void ReplaceMetric(uint32_t interface_index,
    167                      RoutingTableEntry* entry,
    168                      uint32_t metric);
    169 
    170   static const char kRouteFlushPath4[];
    171   static const char kRouteFlushPath6[];
    172 
    173   Tables tables_;
    174 
    175   base::Callback<void(const RTNLMessage&)> route_callback_;
    176   std::unique_ptr<RTNLListener> route_listener_;
    177   std::deque<Query> route_queries_;
    178 
    179   // Cache singleton pointer for performance and test purposes.
    180   RTNLHandler* rtnl_handler_;
    181 
    182   DISALLOW_COPY_AND_ASSIGN(RoutingTable);
    183 };
    184 
    185 }  // namespace shill
    186 
    187 #endif  // SHILL_ROUTING_TABLE_H_
    188