blob: 8a151f386601e200b1f0947f3d090d628d56fcae [file] [log] [blame]
mukesh agrawald4ef6772012-02-21 16:28:04 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewart75e89d22011-08-01 10:00:02 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Chana6bfe872012-09-26 09:48:34 -07005#ifndef SHILL_ROUTING_TABLE_H_
6#define SHILL_ROUTING_TABLE_H_
Paul Stewart75e89d22011-08-01 10:00:02 -07007
Darin Petkovabf6d282012-05-08 15:49:05 +02008#include <deque>
Ben Chancd477322014-10-17 14:19:30 -07009#include <memory>
Paul Stewart75e89d22011-08-01 10:00:02 -070010#include <string>
Alex Vakulenko8a532292014-06-16 17:18:44 -070011#include <unordered_map>
Hristo Stefanoved2c28c2011-11-29 15:37:30 -080012#include <vector>
Paul Stewart75e89d22011-08-01 10:00:02 -070013
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#include <base/callback.h>
Paul Stewart0d2ada32011-08-09 17:01:57 -070015#include <base/lazy_instance.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070016#include <base/memory/ref_counted.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070017
Peter Qiu8d6b5972014-10-28 15:33:34 -070018#include "shill/net/ip_address.h"
19#include "shill/net/rtnl_message.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070020#include "shill/refptr_types.h"
Paul Stewart75e89d22011-08-01 10:00:02 -070021
Paul Stewart75e89d22011-08-01 10:00:02 -070022namespace shill {
23
Paul Stewartf748a362012-03-07 12:01:20 -080024class RTNLHandler;
Paul Stewart75e89d22011-08-01 10:00:02 -070025class RTNLListener;
Liam McLoughlinf4baef22012-08-01 19:08:25 -070026struct RoutingTableEntry;
Paul Stewart75e89d22011-08-01 10:00:02 -070027
28// This singleton maintains an in-process copy of the routing table on
29// a per-interface basis. It offers the ability for other modules to
30// make modifications to the routing table, centered around setting the
31// default route for an interface or modifying its metric (priority).
32class RoutingTable {
33 public:
Paul Stewart6db7b242014-05-02 15:34:21 -070034 typedef std::vector<RoutingTableEntry> TableEntryVector;
Alex Vakulenko8a532292014-06-16 17:18:44 -070035 typedef std::unordered_map<int, TableEntryVector> Tables;
Paul Stewart6db7b242014-05-02 15:34:21 -070036
Paul Stewarte93b0382012-04-24 13:11:28 -070037 struct Query {
Darin Petkovabf6d282012-05-08 15:49:05 +020038 // Callback::Run(interface_index, entry)
Paul Stewart1a212a62015-06-16 13:13:10 -070039 typedef base::Callback<void(int, const RoutingTableEntry&)> Callback;
Darin Petkovabf6d282012-05-08 15:49:05 +020040
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010041 Query() : sequence(0), tag(0), table_id(0) {}
Ben Chan7fab8972014-08-10 17:14:46 -070042 Query(uint32_t sequence_in,
Darin Petkovabf6d282012-05-08 15:49:05 +020043 int tag_in,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010044 Callback callback_in,
45 uint8_t table_id_in)
Darin Petkovabf6d282012-05-08 15:49:05 +020046 : sequence(sequence_in),
47 tag(tag_in),
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010048 callback(callback_in),
49 table_id(table_id_in) {}
Darin Petkovabf6d282012-05-08 15:49:05 +020050
Ben Chan7fab8972014-08-10 17:14:46 -070051 uint32_t sequence;
Paul Stewarte93b0382012-04-24 13:11:28 -070052 int tag;
Darin Petkovabf6d282012-05-08 15:49:05 +020053 Callback callback;
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010054 uint8_t table_id;
Paul Stewarte93b0382012-04-24 13:11:28 -070055 };
56
Paul Stewart0d2ada32011-08-09 17:01:57 -070057 virtual ~RoutingTable();
58
Paul Stewart1a212a62015-06-16 13:13:10 -070059 static RoutingTable* GetInstance();
Paul Stewart75e89d22011-08-01 10:00:02 -070060
Paul Stewartdd60e452011-08-08 11:38:36 -070061 virtual void Start();
62 virtual void Stop();
Paul Stewart75e89d22011-08-01 10:00:02 -070063
Paul Stewartc8f4bef2011-12-13 09:45:51 -080064 // Add an entry to the routing table.
Paul Stewart1a212a62015-06-16 13:13:10 -070065 virtual bool AddRoute(int interface_index, const RoutingTableEntry& entry);
Paul Stewart75e89d22011-08-01 10:00:02 -070066
Paul Stewartc8f4bef2011-12-13 09:45:51 -080067 // Get the default route associated with an interface of a given addr family.
mukesh agrawald4ef6772012-02-21 16:28:04 -080068 // The route is copied into |*entry|.
Paul Stewartdd60e452011-08-08 11:38:36 -070069 virtual bool GetDefaultRoute(int interface_index,
70 IPAddress::Family family,
Paul Stewart1a212a62015-06-16 13:13:10 -070071 RoutingTableEntry* entry);
Paul Stewart75e89d22011-08-01 10:00:02 -070072
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070073 // Set the default route for an interface with index |interface_index|,
74 // given the IPAddress of the gateway |gateway_address| and priority
75 // |metric|.
Paul Stewartdd60e452011-08-08 11:38:36 -070076 virtual bool SetDefaultRoute(int interface_index,
Paul Stewart1a212a62015-06-16 13:13:10 -070077 const IPAddress& gateway_address,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010078 uint32_t metric,
79 uint8_t table_id);
Paul Stewart75e89d22011-08-01 10:00:02 -070080
Ben Chana6bfe872012-09-26 09:48:34 -070081 // Configure routing table entries from the "routes" portion of |ipconfig|.
Paul Stewart3f68bb12012-03-15 13:33:10 -070082 // Returns true if all routes were installed successfully, false otherwise.
83 virtual bool ConfigureRoutes(int interface_index,
Paul Stewart1a212a62015-06-16 13:13:10 -070084 const IPConfigRefPtr& ipconfig,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010085 uint32_t metric,
86 uint8_t table_id);
Paul Stewart3f68bb12012-03-15 13:33:10 -070087
Ben Chana0163122012-09-25 15:10:52 -070088 // Create a blackhole route for a given IP family. Returns true
Ben Chana6bfe872012-09-26 09:48:34 -070089 // on successfully sending the route request, false otherwise.
Ben Chana0163122012-09-25 15:10:52 -070090 virtual bool CreateBlackholeRoute(int interface_index,
Ben Chana6bfe872012-09-26 09:48:34 -070091 IPAddress::Family family,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +010092 uint32_t metric,
93 uint8_t table_id);
Ben Chana0163122012-09-25 15:10:52 -070094
Paul Stewart4a6748d2012-07-17 14:31:36 -070095 // Create a route to a link-attached remote host. |remote_address|
96 // must be directly reachable from |local_address|. Returns true
Ben Chana6bfe872012-09-26 09:48:34 -070097 // on successfully sending the route request, false otherwise.
Paul Stewart4a6748d2012-07-17 14:31:36 -070098 virtual bool CreateLinkRoute(int interface_index,
Paul Stewart1a212a62015-06-16 13:13:10 -070099 const IPAddress& local_address,
100 const IPAddress& remote_address,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100101 uint8_t table_id);
Paul Stewart4a6748d2012-07-17 14:31:36 -0700102
Thieu Lecaef8932012-02-28 16:06:59 -0800103 // Remove routes associated with interface.
Thieu Lefb46caf2012-03-08 11:57:15 -0800104 // Route entries are immediately purged from our copy of the routing table.
105 virtual void FlushRoutes(int interface_index);
Paul Stewart75e89d22011-08-01 10:00:02 -0700106
Paul Stewarte93b0382012-04-24 13:11:28 -0700107 // Iterate over all routing tables removing routes tagged with |tag|.
108 // Route entries are immediately purged from our copy of the routing table.
109 virtual void FlushRoutesWithTag(int tag);
110
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800111 // Flush the routing cache for all interfaces.
112 virtual bool FlushCache();
113
114 // Reset local state for this interface.
Paul Stewartdd60e452011-08-08 11:38:36 -0700115 virtual void ResetTable(int interface_index);
Paul Stewart75e89d22011-08-01 10:00:02 -0700116
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800117 // Set the metric (priority) on existing default routes for an interface.
Ben Chan7fab8972014-08-10 17:14:46 -0700118 virtual void SetDefaultMetric(int interface_index, uint32_t metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700119
Darin Petkovabf6d282012-05-08 15:49:05 +0200120 // Get the default route to |destination| through |interface_index| and create
121 // a host route to that destination. When creating the route, tag our local
122 // entry with |tag|, so we can remove it later. Connections use their
123 // interface index as the tag, so that as they are destroyed, they can remove
124 // all their dependent routes. If |callback| is not null, it will be invoked
125 // when the request-route response is received and the add-route request has
126 // been sent successfully.
Paul Stewart1a212a62015-06-16 13:13:10 -0700127 virtual bool RequestRouteToHost(const IPAddress& destination,
Paul Stewarte93b0382012-04-24 13:11:28 -0700128 int interface_index,
Darin Petkovabf6d282012-05-08 15:49:05 +0200129 int tag,
Paul Stewart1a212a62015-06-16 13:13:10 -0700130 const Query::Callback& callback,
Prabhu Kaliamoorthi762bfb82015-02-06 13:17:08 +0100131 uint8_t table_id);
Darin Petkovabf6d282012-05-08 15:49:05 +0200132
Paul Stewart0d2ada32011-08-09 17:01:57 -0700133 protected:
Paul Stewart75e89d22011-08-01 10:00:02 -0700134 RoutingTable();
Paul Stewart0d2ada32011-08-09 17:01:57 -0700135
136 private:
137 friend struct base::DefaultLazyInstanceTraits<RoutingTable>;
138 friend class RoutingTableTest;
Paul Stewart75e89d22011-08-01 10:00:02 -0700139
Paul Stewart1a212a62015-06-16 13:13:10 -0700140 static bool ParseRoutingTableMessage(const RTNLMessage& message,
141 int* interface_index,
142 RoutingTableEntry* entry);
143 void RouteMsgHandler(const RTNLMessage& msg);
Ben Chan7fab8972014-08-10 17:14:46 -0700144 bool ApplyRoute(uint32_t interface_index,
Paul Stewart1a212a62015-06-16 13:13:10 -0700145 const RoutingTableEntry& entry,
Paul Stewart9a908082011-08-31 12:18:48 -0700146 RTNLMessage::Mode mode,
Paul Stewart75e89d22011-08-01 10:00:02 -0700147 unsigned int flags);
mukesh agrawald4ef6772012-02-21 16:28:04 -0800148 // Get the default route associated with an interface of a given addr family.
149 // A pointer to the route is placed in |*entry|.
150 virtual bool GetDefaultRouteInternal(int interface_index,
151 IPAddress::Family family,
Paul Stewart1a212a62015-06-16 13:13:10 -0700152 RoutingTableEntry** entry);
mukesh agrawald4ef6772012-02-21 16:28:04 -0800153
Ben Chan7fab8972014-08-10 17:14:46 -0700154 void ReplaceMetric(uint32_t interface_index,
Paul Stewart1a212a62015-06-16 13:13:10 -0700155 RoutingTableEntry* entry,
Ben Chan7fab8972014-08-10 17:14:46 -0700156 uint32_t metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700157
158 static const char kRouteFlushPath4[];
159 static const char kRouteFlushPath6[];
160
Paul Stewart6db7b242014-05-02 15:34:21 -0700161 Tables tables_;
Hristo Stefanoved2c28c2011-11-29 15:37:30 -0800162
Paul Stewart1a212a62015-06-16 13:13:10 -0700163 base::Callback<void(const RTNLMessage&)> route_callback_;
Ben Chancd477322014-10-17 14:19:30 -0700164 std::unique_ptr<RTNLListener> route_listener_;
Darin Petkovabf6d282012-05-08 15:49:05 +0200165 std::deque<Query> route_queries_;
Paul Stewartf748a362012-03-07 12:01:20 -0800166
167 // Cache singleton pointer for performance and test purposes.
Paul Stewart1a212a62015-06-16 13:13:10 -0700168 RTNLHandler* rtnl_handler_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700169
170 DISALLOW_COPY_AND_ASSIGN(RoutingTable);
171};
172
173} // namespace shill
174
Ben Chana6bfe872012-09-26 09:48:34 -0700175#endif // SHILL_ROUTING_TABLE_H_