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