blob: d56465c8aef80f84d7f25c34d846df8b7f906baf [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_ROUTING_TABLE_H_
#define SHILL_ROUTING_TABLE_H_
#include <deque>
#include <string>
#include <vector>
#include <base/callback.h>
#include <base/hash_tables.h>
#include <base/lazy_instance.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include "shill/ip_address.h"
#include "shill/refptr_types.h"
#include "shill/rtnl_message.h"
namespace shill {
class RTNLHandler;
class RTNLListener;
struct RoutingTableEntry;
// This singleton maintains an in-process copy of the routing table on
// a per-interface basis. It offers the ability for other modules to
// make modifications to the routing table, centered around setting the
// default route for an interface or modifying its metric (priority).
class RoutingTable {
public:
struct Query {
// Callback::Run(interface_index, entry)
typedef base::Callback<void(int, const RoutingTableEntry &)> Callback;
Query() : sequence(0), tag(0) {}
Query(uint32 sequence_in,
int tag_in,
Callback callback_in)
: sequence(sequence_in),
tag(tag_in),
callback(callback_in) {}
uint32 sequence;
int tag;
Callback callback;
};
virtual ~RoutingTable();
static RoutingTable *GetInstance();
virtual void Start();
virtual void Stop();
// Add an entry to the routing table.
virtual bool AddRoute(int interface_index, const RoutingTableEntry &entry);
// Get the default route associated with an interface of a given addr family.
// The route is copied into |*entry|.
virtual bool GetDefaultRoute(int interface_index,
IPAddress::Family family,
RoutingTableEntry *entry);
// Set the default route for an interface with index |interface_index|,
// given the IPAddress of the gateway |gateway_address| and priority
// |metric|.
virtual bool SetDefaultRoute(int interface_index,
const IPAddress &gateway_address,
uint32 metric);
// Configure routing table entries from the "routes" portion of |ipconfig|.
// Returns true if all routes were installed successfully, false otherwise.
virtual bool ConfigureRoutes(int interface_index,
const IPConfigRefPtr &ipconfig,
uint32 metric);
// Create a blackhole route for a given IP family. Returns true
// on successfully sending the route request, false otherwise.
virtual bool CreateBlackholeRoute(int interface_index,
IPAddress::Family family,
uint32 metric);
// Create a route to a link-attached remote host. |remote_address|
// must be directly reachable from |local_address|. Returns true
// on successfully sending the route request, false otherwise.
virtual bool CreateLinkRoute(int interface_index,
const IPAddress &local_address,
const IPAddress &remote_address);
// Remove routes associated with interface.
// Route entries are immediately purged from our copy of the routing table.
virtual void FlushRoutes(int interface_index);
// Iterate over all routing tables removing routes tagged with |tag|.
// Route entries are immediately purged from our copy of the routing table.
virtual void FlushRoutesWithTag(int tag);
// Flush the routing cache for all interfaces.
virtual bool FlushCache();
// Reset local state for this interface.
virtual void ResetTable(int interface_index);
// Set the metric (priority) on existing default routes for an interface.
virtual void SetDefaultMetric(int interface_index, uint32 metric);
// Get the default route to |destination| through |interface_index| and create
// a host route to that destination. When creating the route, tag our local
// entry with |tag|, so we can remove it later. Connections use their
// interface index as the tag, so that as they are destroyed, they can remove
// all their dependent routes. If |callback| is not null, it will be invoked
// when the request-route response is received and the add-route request has
// been sent successfully.
virtual bool RequestRouteToHost(const IPAddress &destination,
int interface_index,
int tag,
const Query::Callback &callback);
protected:
RoutingTable();
private:
friend struct base::DefaultLazyInstanceTraits<RoutingTable>;
friend class RoutingTableTest;
static bool ParseRoutingTableMessage(const RTNLMessage &message,
int *interface_index,
RoutingTableEntry *entry);
void RouteMsgHandler(const RTNLMessage &msg);
bool ApplyRoute(uint32 interface_index,
const RoutingTableEntry &entry,
RTNLMessage::Mode mode,
unsigned int flags);
// Get the default route associated with an interface of a given addr family.
// A pointer to the route is placed in |*entry|.
virtual bool GetDefaultRouteInternal(int interface_index,
IPAddress::Family family,
RoutingTableEntry **entry);
void ReplaceMetric(uint32 interface_index,
RoutingTableEntry *entry,
uint32 metric);
static const char kRouteFlushPath4[];
static const char kRouteFlushPath6[];
base::hash_map<int, std::vector<RoutingTableEntry> > tables_; // NOLINT
// NOLINT above: hash_map from base, no need to #include <hash_map>.
base::Callback<void(const RTNLMessage &)> route_callback_;
scoped_ptr<RTNLListener> route_listener_;
std::deque<Query> route_queries_;
// Cache singleton pointer for performance and test purposes.
RTNLHandler *rtnl_handler_;
DISALLOW_COPY_AND_ASSIGN(RoutingTable);
};
} // namespace shill
#endif // SHILL_ROUTING_TABLE_H_