blob: e395d2ebec5dd4cc94b25bd27c565eee05846381 [file] [log] [blame]
Paul Stewarta3c56f92011-05-26 07:08:52 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// 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
11#include <base/callback_old.h>
12#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
20#include "shill/io_handler.h"
21#include "shill/rtnl_listener.h"
22#include "shill/shill_event.h"
23
24struct nlmsghdr;
25
26namespace shill {
27
Paul Stewartc39f1132011-06-22 12:02:28 -070028class IPConfig;
Paul Stewart75e89d22011-08-01 10:00:02 -070029class RTNLMessage;
Darin Petkov633ac6f2011-07-08 13:56:13 -070030class Sockets;
Paul Stewartc39f1132011-06-22 12:02:28 -070031
Darin Petkov633ac6f2011-07-08 13:56:13 -070032// This singleton class is responsible for interacting with the RTNL subsystem.
33// RTNL provides (among other things) access to interface discovery (add/remove
34// events), interface state monitoring and the ability to change interace flags.
35// Similar functionality also exists for IP address configuration for interfaces
36// and IP routing tables.
Paul Stewarta3c56f92011-05-26 07:08:52 -070037//
Darin Petkov633ac6f2011-07-08 13:56:13 -070038// RTNLHandler provides access to these events through a callback system and
39// provides utility functions to make changes to interface, address and routing
40// state.
Paul Stewarta3c56f92011-05-26 07:08:52 -070041class RTNLHandler {
42 public:
Darin Petkov633ac6f2011-07-08 13:56:13 -070043 static const int kRequestLink = 1;
44 static const int kRequestAddr = 2;
45 static const int kRequestRoute = 4;
Paul Stewart75e89d22011-08-01 10:00:02 -070046 static const int kRequestAddr6 = 8;
47 static const int kRequestRoute6 = 16;
Paul Stewarta3c56f92011-05-26 07:08:52 -070048
Paul Stewart0d2ada32011-08-09 17:01:57 -070049 virtual ~RTNLHandler();
50
Paul Stewarta3c56f92011-05-26 07:08:52 -070051 // Since this is a singleton, use RTNHandler::GetInstance()->Foo()
52 static RTNLHandler *GetInstance();
53
Darin Petkov633ac6f2011-07-08 13:56:13 -070054 // This starts the event-monitoring function of the RTNL handler. This
55 // function requires an EventDispatcher pointer so it can add itself to the
56 // event loop.
Paul Stewartdd60e452011-08-08 11:38:36 -070057 virtual void Start(EventDispatcher *dispatcher, Sockets *sockets);
Darin Petkove0a312e2011-07-20 13:45:28 -070058
Paul Stewarta3c56f92011-05-26 07:08:52 -070059 // Add an RTNL event listener to the list of entities that will
60 // be notified of RTNL events.
Paul Stewartdd60e452011-08-08 11:38:36 -070061 virtual void AddListener(RTNLListener *to_add);
Darin Petkove0a312e2011-07-20 13:45:28 -070062
Paul Stewarta3c56f92011-05-26 07:08:52 -070063 // Remove a previously added RTNL event listener
Paul Stewartdd60e452011-08-08 11:38:36 -070064 virtual void RemoveListener(RTNLListener *to_remove);
Paul Stewarta3c56f92011-05-26 07:08:52 -070065
Paul Stewartc39f1132011-06-22 12:02:28 -070066 // Set flags on a network interface that has a kernel index of
Paul Stewarta3c56f92011-05-26 07:08:52 -070067 // 'interface_index'. Only the flags bits set in 'change' will
68 // be set, and they will be set to the corresponding bit in 'flags'.
Paul Stewartdd60e452011-08-08 11:38:36 -070069 virtual void SetInterfaceFlags(int interface_index,
70 unsigned int flags,
71 unsigned int change);
Darin Petkove0a312e2011-07-20 13:45:28 -070072
Paul Stewartc39f1132011-06-22 12:02:28 -070073 // Set address of a network interface that has a kernel index of
74 // 'interface_index'.
Paul Stewartdd60e452011-08-08 11:38:36 -070075 virtual bool AddInterfaceAddress(int interface_index, const IPConfig &config);
Darin Petkove0a312e2011-07-20 13:45:28 -070076
Paul Stewartc39f1132011-06-22 12:02:28 -070077 // Remove address from a network interface that has a kernel index of
78 // 'interface_index'.
Paul Stewartdd60e452011-08-08 11:38:36 -070079 virtual bool RemoveInterfaceAddress(int interface_index,
80 const IPConfig &config);
Darin Petkove0a312e2011-07-20 13:45:28 -070081
Paul Stewarta3c56f92011-05-26 07:08:52 -070082 // Request that various tables (link, address, routing) tables be
83 // exhaustively dumped via RTNL. As results arrive from the kernel
84 // they will be broadcast to all listeners. The possible values
85 // (multiple can be ORred together) are below.
Paul Stewartdd60e452011-08-08 11:38:36 -070086 virtual void RequestDump(int request_flags);
Paul Stewarta3c56f92011-05-26 07:08:52 -070087
Darin Petkove0a312e2011-07-20 13:45:28 -070088 // Returns the index of interface |interface_name|, or -1 if unable to
89 // determine the index.
Paul Stewartdd60e452011-08-08 11:38:36 -070090 virtual int GetInterfaceIndex(const std::string &interface_name);
Darin Petkove0a312e2011-07-20 13:45:28 -070091
Paul Stewart75e89d22011-08-01 10:00:02 -070092 // Send a formatted RTNL message. The sequence number in the message is set.
Paul Stewartdd60e452011-08-08 11:38:36 -070093 virtual bool SendMessage(RTNLMessage *message);
Paul Stewart75e89d22011-08-01 10:00:02 -070094
Paul Stewart0d2ada32011-08-09 17:01:57 -070095 protected:
96 RTNLHandler();
97
Paul Stewarta3c56f92011-05-26 07:08:52 -070098 private:
Paul Stewart0d2ada32011-08-09 17:01:57 -070099 friend struct base::DefaultLazyInstanceTraits<RTNLHandler>;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700100 friend class CellularTest;
Darin Petkov633ac6f2011-07-08 13:56:13 -0700101 friend class DeviceInfoTest;
Darin Petkove0a312e2011-07-20 13:45:28 -0700102 friend class ModemTest;
103 friend class RTNLHandlerTest;
Paul Stewart75e89d22011-08-01 10:00:02 -0700104 friend class RoutingTableTest;
Paul Stewart0d2ada32011-08-09 17:01:57 -0700105
Darin Petkovca432fc2011-07-08 15:56:57 -0700106 FRIEND_TEST(RTNLListenerTest, NoRun);
107 FRIEND_TEST(RTNLListenerTest, Run);
Darin Petkov633ac6f2011-07-08 13:56:13 -0700108
Paul Stewart65c40f52011-08-08 07:27:46 -0700109 // This stops the event-monitoring function of the RTNL handler -- it is
110 // private since it will never happen in normal running, but is useful for
111 // tests.
112 void Stop();
113
Paul Stewarta3c56f92011-05-26 07:08:52 -0700114 // Dispatches an rtnl message to all listeners
Chris Masone2aa97072011-08-09 17:35:08 -0700115 void DispatchEvent(int type, const RTNLMessage &msg);
Paul Stewarta3c56f92011-05-26 07:08:52 -0700116 // Send the next table-dump request to the kernel
117 void NextRequest(uint32_t seq);
118 // Parse an incoming rtnl message from the kernel
119 void ParseRTNL(InputData *data);
Paul Stewartc39f1132011-06-22 12:02:28 -0700120 bool AddressRequest(int interface_index, int cmd, int flags,
121 const IPConfig &config);
Paul Stewarta3c56f92011-05-26 07:08:52 -0700122
Darin Petkov633ac6f2011-07-08 13:56:13 -0700123 Sockets *sockets_;
Paul Stewarta3c56f92011-05-26 07:08:52 -0700124 bool in_request_;
125
126 int rtnl_socket_;
127 uint32_t request_flags_;
128 uint32_t request_sequence_;
129
130 std::vector<RTNLListener *> listeners_;
131 scoped_ptr<Callback1<InputData *>::Type> rtnl_callback_;
132 scoped_ptr<IOInputHandler> rtnl_handler_;
133
Paul Stewarta3c56f92011-05-26 07:08:52 -0700134 DISALLOW_COPY_AND_ASSIGN(RTNLHandler);
135};
136
137} // namespace shill
138
139#endif // SHILL_RTNL_HANDLER_