blob: 5d5556b3875f6df6ceefd62342d184e670fc455f [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>
Paul Stewart75e89d22011-08-01 10:00:02 -07009#include <string>
Hristo Stefanoved2c28c2011-11-29 15:37:30 -080010#include <vector>
Paul Stewart75e89d22011-08-01 10:00:02 -070011
Eric Shienbrood3e20a232012-02-16 11:35:56 -050012#include <base/callback.h>
Ben Chana0ddf462014-02-06 11:32:42 -080013#include <base/containers/hash_tables.h>
Paul Stewart0d2ada32011-08-09 17:01:57 -070014#include <base/lazy_instance.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070015#include <base/memory/ref_counted.h>
Paul Stewart75e89d22011-08-01 10:00:02 -070016#include <base/memory/scoped_ptr.h>
17
18#include "shill/ip_address.h"
19#include "shill/refptr_types.h"
20#include "shill/rtnl_message.h"
21
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;
35 typedef base::hash_map<int, TableEntryVector> Tables; // NOLINT
36 // NOLINT above: hash_map from base, no need to #include <hash_map>.
37
Paul Stewarte93b0382012-04-24 13:11:28 -070038 struct Query {
Darin Petkovabf6d282012-05-08 15:49:05 +020039 // Callback::Run(interface_index, entry)
40 typedef base::Callback<void(int, const RoutingTableEntry &)> Callback;
41
Paul Stewarte93b0382012-04-24 13:11:28 -070042 Query() : sequence(0), tag(0) {}
Darin Petkovabf6d282012-05-08 15:49:05 +020043 Query(uint32 sequence_in,
44 int tag_in,
45 Callback callback_in)
46 : sequence(sequence_in),
47 tag(tag_in),
48 callback(callback_in) {}
49
Paul Stewarte93b0382012-04-24 13:11:28 -070050 uint32 sequence;
51 int tag;
Darin Petkovabf6d282012-05-08 15:49:05 +020052 Callback callback;
Paul Stewarte93b0382012-04-24 13:11:28 -070053 };
54
Paul Stewart0d2ada32011-08-09 17:01:57 -070055 virtual ~RoutingTable();
56
Paul Stewart75e89d22011-08-01 10:00:02 -070057 static RoutingTable *GetInstance();
58
Paul Stewartdd60e452011-08-08 11:38:36 -070059 virtual void Start();
60 virtual void Stop();
Paul Stewart75e89d22011-08-01 10:00:02 -070061
Paul Stewartc8f4bef2011-12-13 09:45:51 -080062 // Add an entry to the routing table.
Paul Stewartdd60e452011-08-08 11:38:36 -070063 virtual bool AddRoute(int interface_index, const RoutingTableEntry &entry);
Paul Stewart75e89d22011-08-01 10:00:02 -070064
Paul Stewartc8f4bef2011-12-13 09:45:51 -080065 // Get the default route associated with an interface of a given addr family.
mukesh agrawald4ef6772012-02-21 16:28:04 -080066 // The route is copied into |*entry|.
Paul Stewartdd60e452011-08-08 11:38:36 -070067 virtual bool GetDefaultRoute(int interface_index,
68 IPAddress::Family family,
69 RoutingTableEntry *entry);
Paul Stewart75e89d22011-08-01 10:00:02 -070070
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070071 // Set the default route for an interface with index |interface_index|,
72 // given the IPAddress of the gateway |gateway_address| and priority
73 // |metric|.
Paul Stewartdd60e452011-08-08 11:38:36 -070074 virtual bool SetDefaultRoute(int interface_index,
Paul Stewart5b7ba8c2012-04-18 09:08:00 -070075 const IPAddress &gateway_address,
Paul Stewartdd60e452011-08-08 11:38:36 -070076 uint32 metric);
Paul Stewart75e89d22011-08-01 10:00:02 -070077
Ben Chana6bfe872012-09-26 09:48:34 -070078 // Configure routing table entries from the "routes" portion of |ipconfig|.
Paul Stewart3f68bb12012-03-15 13:33:10 -070079 // Returns true if all routes were installed successfully, false otherwise.
80 virtual bool ConfigureRoutes(int interface_index,
81 const IPConfigRefPtr &ipconfig,
82 uint32 metric);
83
Ben Chana0163122012-09-25 15:10:52 -070084 // Create a blackhole route for a given IP family. Returns true
Ben Chana6bfe872012-09-26 09:48:34 -070085 // on successfully sending the route request, false otherwise.
Ben Chana0163122012-09-25 15:10:52 -070086 virtual bool CreateBlackholeRoute(int interface_index,
Ben Chana6bfe872012-09-26 09:48:34 -070087 IPAddress::Family family,
Ben Chana0163122012-09-25 15:10:52 -070088 uint32 metric);
89
Paul Stewart4a6748d2012-07-17 14:31:36 -070090 // Create a route to a link-attached remote host. |remote_address|
91 // must be directly reachable from |local_address|. Returns true
Ben Chana6bfe872012-09-26 09:48:34 -070092 // on successfully sending the route request, false otherwise.
Paul Stewart4a6748d2012-07-17 14:31:36 -070093 virtual bool CreateLinkRoute(int interface_index,
94 const IPAddress &local_address,
95 const IPAddress &remote_address);
96
Thieu Lecaef8932012-02-28 16:06:59 -080097 // Remove routes associated with interface.
Thieu Lefb46caf2012-03-08 11:57:15 -080098 // Route entries are immediately purged from our copy of the routing table.
99 virtual void FlushRoutes(int interface_index);
Paul Stewart75e89d22011-08-01 10:00:02 -0700100
Paul Stewarte93b0382012-04-24 13:11:28 -0700101 // Iterate over all routing tables removing routes tagged with |tag|.
102 // Route entries are immediately purged from our copy of the routing table.
103 virtual void FlushRoutesWithTag(int tag);
104
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800105 // Flush the routing cache for all interfaces.
106 virtual bool FlushCache();
107
108 // Reset local state for this interface.
Paul Stewartdd60e452011-08-08 11:38:36 -0700109 virtual void ResetTable(int interface_index);
Paul Stewart75e89d22011-08-01 10:00:02 -0700110
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800111 // Set the metric (priority) on existing default routes for an interface.
Paul Stewartdd60e452011-08-08 11:38:36 -0700112 virtual void SetDefaultMetric(int interface_index, uint32 metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700113
Darin Petkovabf6d282012-05-08 15:49:05 +0200114 // Get the default route to |destination| through |interface_index| and create
115 // a host route to that destination. When creating the route, tag our local
116 // entry with |tag|, so we can remove it later. Connections use their
117 // interface index as the tag, so that as they are destroyed, they can remove
118 // all their dependent routes. If |callback| is not null, it will be invoked
119 // when the request-route response is received and the add-route request has
120 // been sent successfully.
Paul Stewartf748a362012-03-07 12:01:20 -0800121 virtual bool RequestRouteToHost(const IPAddress &destination,
Paul Stewarte93b0382012-04-24 13:11:28 -0700122 int interface_index,
Darin Petkovabf6d282012-05-08 15:49:05 +0200123 int tag,
124 const Query::Callback &callback);
125
Paul Stewart0d2ada32011-08-09 17:01:57 -0700126 protected:
Paul Stewart75e89d22011-08-01 10:00:02 -0700127 RoutingTable();
Paul Stewart0d2ada32011-08-09 17:01:57 -0700128
129 private:
130 friend struct base::DefaultLazyInstanceTraits<RoutingTable>;
131 friend class RoutingTableTest;
Paul Stewart75e89d22011-08-01 10:00:02 -0700132
Paul Stewartf748a362012-03-07 12:01:20 -0800133 static bool ParseRoutingTableMessage(const RTNLMessage &message,
134 int *interface_index,
135 RoutingTableEntry *entry);
Chris Masone2aa97072011-08-09 17:35:08 -0700136 void RouteMsgHandler(const RTNLMessage &msg);
Paul Stewart75e89d22011-08-01 10:00:02 -0700137 bool ApplyRoute(uint32 interface_index,
138 const RoutingTableEntry &entry,
Paul Stewart9a908082011-08-31 12:18:48 -0700139 RTNLMessage::Mode mode,
Paul Stewart75e89d22011-08-01 10:00:02 -0700140 unsigned int flags);
mukesh agrawald4ef6772012-02-21 16:28:04 -0800141 // Get the default route associated with an interface of a given addr family.
142 // A pointer to the route is placed in |*entry|.
143 virtual bool GetDefaultRouteInternal(int interface_index,
144 IPAddress::Family family,
145 RoutingTableEntry **entry);
146
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800147 void ReplaceMetric(uint32 interface_index,
mukesh agrawald4ef6772012-02-21 16:28:04 -0800148 RoutingTableEntry *entry,
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800149 uint32 metric);
Paul Stewart75e89d22011-08-01 10:00:02 -0700150
151 static const char kRouteFlushPath4[];
152 static const char kRouteFlushPath6[];
153
Paul Stewart6db7b242014-05-02 15:34:21 -0700154 Tables tables_;
Hristo Stefanoved2c28c2011-11-29 15:37:30 -0800155
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500156 base::Callback<void(const RTNLMessage &)> route_callback_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700157 scoped_ptr<RTNLListener> route_listener_;
Darin Petkovabf6d282012-05-08 15:49:05 +0200158 std::deque<Query> route_queries_;
Paul Stewartf748a362012-03-07 12:01:20 -0800159
160 // Cache singleton pointer for performance and test purposes.
161 RTNLHandler *rtnl_handler_;
Paul Stewart75e89d22011-08-01 10:00:02 -0700162
163 DISALLOW_COPY_AND_ASSIGN(RoutingTable);
164};
165
166} // namespace shill
167
Ben Chana6bfe872012-09-26 09:48:34 -0700168#endif // SHILL_ROUTING_TABLE_H_