• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
QueryQuery53     Query() : sequence(0), tag(0), table_id(0) {}
QueryQuery54     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