blob: 6691531cc5c09125d9c7b0b4edf324e9759981fb [file] [log] [blame]
Paul Stewartf748a362012-03-07 12:01:20 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Paul Stewarta3c56f92011-05-26 07:08:52 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_RTNL_HANDLER_
6#define SHILL_RTNL_HANDLER_
7
Darin Petkove0a312e2011-07-20 13:45:28 -07008#include <string>
Paul Stewarta3c56f92011-05-26 07:08:52 -07009#include <vector>
10
Eric Shienbrood3e20a232012-02-16 11:35:56 -050011#include <base/callback.h>
Paul Stewarta3c56f92011-05-26 07:08:52 -070012#include <base/hash_tables.h>
Paul Stewart0d2ada32011-08-09 17:01:57 -070013#include <base/lazy_instance.h>
Paul Stewarta3c56f92011-05-26 07:08:52 -070014#include <base/memory/ref_counted.h>
15#include <base/memory/scoped_ptr.h>
Darin Petkovca432fc2011-07-08 15:56:57 -070016#include <gtest/gtest_prod.h> // for FRIEND_TEST
Paul Stewarta3c56f92011-05-26 07:08:52 -070017
18#include "shill/device.h"
19
Paul Stewart26b327e2011-10-19 11:38:09 -070020#include "shill/event_dispatcher.h"
Paul Stewarta3c56f92011-05-26 07:08:52 -070021#include "shill/io_handler.h"
22#include "shill/rtnl_listener.h"
Paul Stewart9a908082011-08-31 12:18:48 -070023#include "shill/rtnl_message.h"
Paul Stewarta3c56f92011-05-26 07:08:52 -070024
25struct nlmsghdr;
26
27namespace shill {
28
Paul Stewart5f06a0e2012-12-20 11:11:33 -080029class Error;
Paul Stewartc39f1132011-06-22 12:02:28 -070030class IPConfig;
Darin Petkov633ac6f2011-07-08 13:56:13 -070031class Sockets;
Paul Stewartc39f1132011-06-22 12:02:28 -070032
Darin Petkov633ac6f2011-07-08 13:56:13 -070033// This singleton class is responsible for interacting with the RTNL subsystem.
34// RTNL provides (among other things) access to interface discovery (add/remove
35// events), interface state monitoring and the ability to change interace flags.
36// Similar functionality also exists for IP address configuration for interfaces
37// and IP routing tables.
Paul Stewarta3c56f92011-05-26 07:08:52 -070038//
Darin Petkov633ac6f2011-07-08 13:56:13 -070039// RTNLHandler provides access to these events through a callback system and
40// provides utility functions to make changes to interface, address and routing
41// state.
Paul Stewarta3c56f92011-05-26 07:08:52 -070042class RTNLHandler {
43 public:
Darin Petkov633ac6f2011-07-08 13:56:13 -070044 static const int kRequestLink = 1;
45 static const int kRequestAddr = 2;
46 static const int kRequestRoute = 4;
Paul Stewarta3c56f92011-05-26 07:08:52 -070047
Paul Stewart0d2ada32011-08-09 17:01:57 -070048 virtual ~RTNLHandler();
49
Paul Stewarta3c56f92011-05-26 07:08:52 -070050 // Since this is a singleton, use RTNHandler::GetInstance()->Foo()
51 static RTNLHandler *GetInstance();
52
Darin Petkov633ac6f2011-07-08 13:56:13 -070053 // This starts the event-monitoring function of the RTNL handler. This
54 // function requires an EventDispatcher pointer so it can add itself to the
55 // event loop.
Paul Stewartdd60e452011-08-08 11:38:36 -070056 virtual void Start(EventDispatcher *dispatcher, Sockets *sockets);
Darin Petkove0a312e2011-07-20 13:45:28 -070057
Paul Stewarta3c56f92011-05-26 07:08:52 -070058 // Add an RTNL event listener to the list of entities that will
59 // be notified of RTNL events.
Paul Stewartdd60e452011-08-08 11:38:36 -070060 virtual void AddListener(RTNLListener *to_add);
Darin Petkove0a312e2011-07-20 13:45:28 -070061
Paul Stewarta3c56f92011-05-26 07:08:52 -070062 // Remove a previously added RTNL event listener
Paul Stewartdd60e452011-08-08 11:38:36 -070063 virtual void RemoveListener(RTNLListener *to_remove);
Paul Stewarta3c56f92011-05-26 07:08:52 -070064
Paul Stewartc39f1132011-06-22 12:02:28 -070065 // Set flags on a network interface that has a kernel index of
Paul Stewarta3c56f92011-05-26 07:08:52 -070066 // 'interface_index'. Only the flags bits set in 'change' will
67 // be set, and they will be set to the corresponding bit in 'flags'.
Paul Stewartdd60e452011-08-08 11:38:36 -070068 virtual void SetInterfaceFlags(int interface_index,
69 unsigned int flags,
70 unsigned int change);
Darin Petkove0a312e2011-07-20 13:45:28 -070071
Paul Stewartc39f1132011-06-22 12:02:28 -070072 // Set address of a network interface that has a kernel index of
73 // 'interface_index'.
Paul Stewart9a908082011-08-31 12:18:48 -070074 virtual bool AddInterfaceAddress(int interface_index,
75 const IPAddress &local,
Paul Stewart48100b02012-03-19 07:53:52 -070076 const IPAddress &gateway,
77 const IPAddress &peer);
Darin Petkove0a312e2011-07-20 13:45:28 -070078
Paul Stewartc39f1132011-06-22 12:02:28 -070079 // Remove address from a network interface that has a kernel index of
80 // 'interface_index'.
Paul Stewartdd60e452011-08-08 11:38:36 -070081 virtual bool RemoveInterfaceAddress(int interface_index,
Paul Stewart9a908082011-08-31 12:18:48 -070082 const IPAddress &local);
Darin Petkove0a312e2011-07-20 13:45:28 -070083
Paul Stewartcba0f7f2012-02-29 16:33:05 -080084 // Remove a network interface from the kernel.
85 virtual bool RemoveInterface(int interface_index);
86
Paul Stewarta3c56f92011-05-26 07:08:52 -070087 // Request that various tables (link, address, routing) tables be
88 // exhaustively dumped via RTNL. As results arrive from the kernel
89 // they will be broadcast to all listeners. The possible values
90 // (multiple can be ORred together) are below.
Paul Stewartdd60e452011-08-08 11:38:36 -070091 virtual void RequestDump(int request_flags);
Paul Stewarta3c56f92011-05-26 07:08:52 -070092
Darin Petkove0a312e2011-07-20 13:45:28 -070093 // Returns the index of interface |interface_name|, or -1 if unable to
94 // determine the index.
Paul Stewartdd60e452011-08-08 11:38:36 -070095 virtual int GetInterfaceIndex(const std::string &interface_name);
Darin Petkove0a312e2011-07-20 13:45:28 -070096
Paul Stewart75e89d22011-08-01 10:00:02 -070097 // Send a formatted RTNL message. The sequence number in the message is set.
Paul Stewartdd60e452011-08-08 11:38:36 -070098 virtual bool SendMessage(RTNLMessage *message);
Paul Stewart75e89d22011-08-01 10:00:02 -070099
Paul Stewart0d2ada32011-08-09 17:01:57 -0700100 protected:
101 RTNLHandler();
102
Paul Stewarta3c56f92011-05-26 07:08:52 -0700103 private:
Paul Stewart0d2ada32011-08-09 17:01:57 -0700104 friend struct base::DefaultLazyInstanceTraits<RTNLHandler>;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700105 friend class CellularTest;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700106 friend class DeviceInfoTest;
Darin Petkove0a312e2011-07-20 13:45:28 -0700107 friend class ModemTest;
108 friend class RTNLHandlerTest;
Han Shen4afba202012-12-17 08:48:35 -0800109 friend class RTNLListenerTest;
Paul Stewart75e89d22011-08-01 10:00:02 -0700110 friend class RoutingTableTest;
Paul Stewart0d2ada32011-08-09 17:01:57 -0700111
Darin Petkovca432fc2011-07-08 15:56:57 -0700112 FRIEND_TEST(RTNLListenerTest, NoRun);
113 FRIEND_TEST(RTNLListenerTest, Run);
Thieu Lecaef8932012-02-28 16:06:59 -0800114 FRIEND_TEST(RoutingTableTest, RouteDeleteForeign);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700115
Julius Wernerf253c842012-12-20 14:52:30 -0800116 static const int kReceiveBufferSize;
117
Paul Stewart65c40f52011-08-08 07:27:46 -0700118 // This stops the event-monitoring function of the RTNL handler -- it is
119 // private since it will never happen in normal running, but is useful for
120 // tests.
121 void Stop();
122
Paul Stewarta3c56f92011-05-26 07:08:52 -0700123 // Dispatches an rtnl message to all listeners
Chris Masone2aa97072011-08-09 17:35:08 -0700124 void DispatchEvent(int type, const RTNLMessage &msg);
Paul Stewarta3c56f92011-05-26 07:08:52 -0700125 // Send the next table-dump request to the kernel
Paul Stewartf748a362012-03-07 12:01:20 -0800126 void NextRequest(uint32 seq);
Paul Stewarta3c56f92011-05-26 07:08:52 -0700127 // Parse an incoming rtnl message from the kernel
128 void ParseRTNL(InputData *data);
Paul Stewarta3c56f92011-05-26 07:08:52 -0700129
Paul Stewart9a908082011-08-31 12:18:48 -0700130 bool AddressRequest(int interface_index,
131 RTNLMessage::Mode mode,
132 int flags,
133 const IPAddress &local,
Paul Stewart48100b02012-03-19 07:53:52 -0700134 const IPAddress &gateway,
135 const IPAddress &peer);
Paul Stewart5f06a0e2012-12-20 11:11:33 -0800136
137 // Called by the RTNL read handler on exceptional events.
138 void OnReadError(const Error &error);
139
Darin Petkov633ac6f2011-07-08 13:56:13 -0700140 Sockets *sockets_;
Paul Stewarta3c56f92011-05-26 07:08:52 -0700141 bool in_request_;
142
143 int rtnl_socket_;
Paul Stewartf748a362012-03-07 12:01:20 -0800144 uint32 request_flags_;
145 uint32 request_sequence_;
146 uint32 last_dump_sequence_;
Paul Stewarta3c56f92011-05-26 07:08:52 -0700147
148 std::vector<RTNLListener *> listeners_;
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500149 base::Callback<void(InputData *)> rtnl_callback_;
Paul Stewart26b327e2011-10-19 11:38:09 -0700150 scoped_ptr<IOHandler> rtnl_handler_;
Paul Stewarta3c56f92011-05-26 07:08:52 -0700151
Paul Stewarta3c56f92011-05-26 07:08:52 -0700152 DISALLOW_COPY_AND_ASSIGN(RTNLHandler);
153};
154
155} // namespace shill
156
157#endif // SHILL_RTNL_HANDLER_