blob: 00426a78edd3830a99dc5d78169089e334069611 [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>
14
15#include "shill/device.h"
16
17#include "shill/io_handler.h"
18#include "shill/rtnl_listener.h"
19#include "shill/shill_event.h"
20
21struct nlmsghdr;
22
23namespace shill {
24
25// This singleton class is responsible for interacting with the RTNL
26// subsystem. RTNL provides (among other things) access to interface
27// discovery (add/remove events), interface state monitoring and the
28// ability to change interace flags. Similar functionality also exists
29// for IP address configuration for interfaces and IP routing tables.
30//
31// RTNLHandler provides access to these events through a callback
32// system and provides utility functions to make changes to interface,
33// address and routing state.
34class RTNLHandler {
35 public:
36 RTNLHandler();
37 ~RTNLHandler();
38
39 // Since this is a singleton, use RTNHandler::GetInstance()->Foo()
40 static RTNLHandler *GetInstance();
41
42 // This starts the event-monitoring function of the RTNL handler.
43 // This function requires an EventDispatcher pointer so it can add
44 // itself to the event loop.
45 void Start(EventDispatcher *dispatcher);
46 // This stops the event-monitoring function of the RTNL handler
47 void Stop();
48
49 // Add an RTNL event listener to the list of entities that will
50 // be notified of RTNL events.
51 void AddListener(RTNLListener *to_add);
52 // Remove a previously added RTNL event listener
53 void RemoveListener(RTNLListener *to_remove);
54
55 // Set flags on a network interface that has an kernel index of
56 // 'interface_index'. Only the flags bits set in 'change' will
57 // be set, and they will be set to the corresponding bit in 'flags'.
58 void SetInterfaceFlags(int interface_index, unsigned int flags,
59 unsigned int change);
60 // Request that various tables (link, address, routing) tables be
61 // exhaustively dumped via RTNL. As results arrive from the kernel
62 // they will be broadcast to all listeners. The possible values
63 // (multiple can be ORred together) are below.
64 void RequestDump(int request_flags);
65
66 static const int kRequestLink = 1;
67 static const int kRequestAddr = 2;
68 static const int kRequestRoute = 4;
69
70 private:
71 // Dispatches an rtnl message to all listeners
72 void DispatchEvent(int type, struct nlmsghdr *hdr);
73 // Send the next table-dump request to the kernel
74 void NextRequest(uint32_t seq);
75 // Parse an incoming rtnl message from the kernel
76 void ParseRTNL(InputData *data);
77
78 bool running_;
79 bool in_request_;
80
81 int rtnl_socket_;
82 uint32_t request_flags_;
83 uint32_t request_sequence_;
84
85 std::vector<RTNLListener *> listeners_;
86 scoped_ptr<Callback1<InputData *>::Type> rtnl_callback_;
87 scoped_ptr<IOInputHandler> rtnl_handler_;
88
89 friend class RTNLHandlerTest;
90 DISALLOW_COPY_AND_ASSIGN(RTNLHandler);
91};
92
93} // namespace shill
94
95#endif // SHILL_RTNL_HANDLER_