blob: 905676b07be63ff752277f32fe29c12b54dae31d [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
8#include <vector>
9
10#include <base/callback_old.h>
11#include <base/hash_tables.h>
12#include <base/memory/ref_counted.h>
13#include <base/memory/scoped_ptr.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070014#include <base/memory/singleton.h>
Darin Petkovca432fc2011-07-08 15:56:57 -070015#include <gtest/gtest_prod.h> // for FRIEND_TEST
Paul Stewarta3c56f92011-05-26 07:08:52 -070016
17#include "shill/device.h"
18
19#include "shill/io_handler.h"
20#include "shill/rtnl_listener.h"
21#include "shill/shill_event.h"
22
23struct nlmsghdr;
24
25namespace shill {
26
Paul Stewartc39f1132011-06-22 12:02:28 -070027class IPConfig;
Darin Petkov633ac6f2011-07-08 13:56:13 -070028class Sockets;
Paul Stewartc39f1132011-06-22 12:02:28 -070029
Darin Petkov633ac6f2011-07-08 13:56:13 -070030// This singleton class is responsible for interacting with the RTNL subsystem.
31// RTNL provides (among other things) access to interface discovery (add/remove
32// events), interface state monitoring and the ability to change interace flags.
33// Similar functionality also exists for IP address configuration for interfaces
34// and IP routing tables.
Paul Stewarta3c56f92011-05-26 07:08:52 -070035//
Darin Petkov633ac6f2011-07-08 13:56:13 -070036// RTNLHandler provides access to these events through a callback system and
37// provides utility functions to make changes to interface, address and routing
38// state.
Paul Stewarta3c56f92011-05-26 07:08:52 -070039class RTNLHandler {
40 public:
Darin Petkov633ac6f2011-07-08 13:56:13 -070041 static const int kRequestLink = 1;
42 static const int kRequestAddr = 2;
43 static const int kRequestRoute = 4;
Paul Stewarta3c56f92011-05-26 07:08:52 -070044
45 // Since this is a singleton, use RTNHandler::GetInstance()->Foo()
46 static RTNLHandler *GetInstance();
47
Darin Petkov633ac6f2011-07-08 13:56:13 -070048 // This starts the event-monitoring function of the RTNL handler. This
49 // function requires an EventDispatcher pointer so it can add itself to the
50 // event loop.
51 void Start(EventDispatcher *dispatcher, Sockets *sockets);
Paul Stewarta3c56f92011-05-26 07:08:52 -070052 // This stops the event-monitoring function of the RTNL handler
53 void Stop();
54
55 // Add an RTNL event listener to the list of entities that will
56 // be notified of RTNL events.
57 void AddListener(RTNLListener *to_add);
58 // Remove a previously added RTNL event listener
59 void RemoveListener(RTNLListener *to_remove);
60
Paul Stewartc39f1132011-06-22 12:02:28 -070061 // Set flags on a network interface that has a kernel index of
Paul Stewarta3c56f92011-05-26 07:08:52 -070062 // 'interface_index'. Only the flags bits set in 'change' will
63 // be set, and they will be set to the corresponding bit in 'flags'.
64 void SetInterfaceFlags(int interface_index, unsigned int flags,
65 unsigned int change);
Paul Stewartc39f1132011-06-22 12:02:28 -070066 // Set address of a network interface that has a kernel index of
67 // 'interface_index'.
68 bool AddInterfaceAddress(int interface_index, const IPConfig &config);
69 // Remove address from a network interface that has a kernel index of
70 // 'interface_index'.
71 bool RemoveInterfaceAddress(int interface_index, const IPConfig &config);
Paul Stewarta3c56f92011-05-26 07:08:52 -070072 // Request that various tables (link, address, routing) tables be
73 // exhaustively dumped via RTNL. As results arrive from the kernel
74 // they will be broadcast to all listeners. The possible values
75 // (multiple can be ORred together) are below.
76 void RequestDump(int request_flags);
77
Paul Stewarta3c56f92011-05-26 07:08:52 -070078 private:
Darin Petkov633ac6f2011-07-08 13:56:13 -070079 friend class DeviceInfoTest;
80 friend struct DefaultSingletonTraits<RTNLHandler>;
Darin Petkovca432fc2011-07-08 15:56:57 -070081 FRIEND_TEST(RTNLListenerTest, NoRun);
82 FRIEND_TEST(RTNLListenerTest, Run);
Darin Petkov633ac6f2011-07-08 13:56:13 -070083
84 // Private to ensure that this behaves as a singleton.
85 RTNLHandler();
86 virtual ~RTNLHandler();
87
Paul Stewarta3c56f92011-05-26 07:08:52 -070088 // Dispatches an rtnl message to all listeners
89 void DispatchEvent(int type, struct nlmsghdr *hdr);
90 // Send the next table-dump request to the kernel
91 void NextRequest(uint32_t seq);
92 // Parse an incoming rtnl message from the kernel
93 void ParseRTNL(InputData *data);
Paul Stewartc39f1132011-06-22 12:02:28 -070094 bool AddressRequest(int interface_index, int cmd, int flags,
95 const IPConfig &config);
Paul Stewarta3c56f92011-05-26 07:08:52 -070096
Darin Petkov633ac6f2011-07-08 13:56:13 -070097 Sockets *sockets_;
Paul Stewarta3c56f92011-05-26 07:08:52 -070098 bool in_request_;
99
100 int rtnl_socket_;
101 uint32_t request_flags_;
102 uint32_t request_sequence_;
103
104 std::vector<RTNLListener *> listeners_;
105 scoped_ptr<Callback1<InputData *>::Type> rtnl_callback_;
106 scoped_ptr<IOInputHandler> rtnl_handler_;
107
Paul Stewarta3c56f92011-05-26 07:08:52 -0700108 DISALLOW_COPY_AND_ASSIGN(RTNLHandler);
109};
110
111} // namespace shill
112
113#endif // SHILL_RTNL_HANDLER_