blob: 62a7389fdc0bb6ad7f05717829f28dc08cc1ffc6 [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>
13#include <base/memory/ref_counted.h>
14#include <base/memory/scoped_ptr.h>
Darin Petkov633ac6f2011-07-08 13:56:13 -070015#include <base/memory/singleton.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;
Darin Petkov633ac6f2011-07-08 13:56:13 -070029class Sockets;
Paul Stewartc39f1132011-06-22 12:02:28 -070030
Darin Petkov633ac6f2011-07-08 13:56:13 -070031// This singleton class is responsible for interacting with the RTNL subsystem.
32// RTNL provides (among other things) access to interface discovery (add/remove
33// events), interface state monitoring and the ability to change interace flags.
34// Similar functionality also exists for IP address configuration for interfaces
35// and IP routing tables.
Paul Stewarta3c56f92011-05-26 07:08:52 -070036//
Darin Petkov633ac6f2011-07-08 13:56:13 -070037// RTNLHandler provides access to these events through a callback system and
38// provides utility functions to make changes to interface, address and routing
39// state.
Paul Stewarta3c56f92011-05-26 07:08:52 -070040class RTNLHandler {
41 public:
Darin Petkov633ac6f2011-07-08 13:56:13 -070042 static const int kRequestLink = 1;
43 static const int kRequestAddr = 2;
44 static const int kRequestRoute = 4;
Paul Stewarta3c56f92011-05-26 07:08:52 -070045
46 // Since this is a singleton, use RTNHandler::GetInstance()->Foo()
47 static RTNLHandler *GetInstance();
48
Darin Petkov633ac6f2011-07-08 13:56:13 -070049 // This starts the event-monitoring function of the RTNL handler. This
50 // function requires an EventDispatcher pointer so it can add itself to the
51 // event loop.
52 void Start(EventDispatcher *dispatcher, Sockets *sockets);
Darin Petkove0a312e2011-07-20 13:45:28 -070053
Paul Stewarta3c56f92011-05-26 07:08:52 -070054 // This stops the event-monitoring function of the RTNL handler
55 void Stop();
56
57 // Add an RTNL event listener to the list of entities that will
58 // be notified of RTNL events.
59 void AddListener(RTNLListener *to_add);
Darin Petkove0a312e2011-07-20 13:45:28 -070060
Paul Stewarta3c56f92011-05-26 07:08:52 -070061 // Remove a previously added RTNL event listener
62 void RemoveListener(RTNLListener *to_remove);
63
Paul Stewartc39f1132011-06-22 12:02:28 -070064 // Set flags on a network interface that has a kernel index of
Paul Stewarta3c56f92011-05-26 07:08:52 -070065 // 'interface_index'. Only the flags bits set in 'change' will
66 // be set, and they will be set to the corresponding bit in 'flags'.
67 void SetInterfaceFlags(int interface_index, unsigned int flags,
68 unsigned int change);
Darin Petkove0a312e2011-07-20 13:45:28 -070069
Paul Stewartc39f1132011-06-22 12:02:28 -070070 // Set address of a network interface that has a kernel index of
71 // 'interface_index'.
72 bool AddInterfaceAddress(int interface_index, const IPConfig &config);
Darin Petkove0a312e2011-07-20 13:45:28 -070073
Paul Stewartc39f1132011-06-22 12:02:28 -070074 // Remove address from a network interface that has a kernel index of
75 // 'interface_index'.
76 bool RemoveInterfaceAddress(int interface_index, const IPConfig &config);
Darin Petkove0a312e2011-07-20 13:45:28 -070077
Paul Stewarta3c56f92011-05-26 07:08:52 -070078 // Request that various tables (link, address, routing) tables be
79 // exhaustively dumped via RTNL. As results arrive from the kernel
80 // they will be broadcast to all listeners. The possible values
81 // (multiple can be ORred together) are below.
82 void RequestDump(int request_flags);
83
Darin Petkove0a312e2011-07-20 13:45:28 -070084 // Returns the index of interface |interface_name|, or -1 if unable to
85 // determine the index.
86 int GetInterfaceIndex(const std::string &interface_name);
87
Paul Stewarta3c56f92011-05-26 07:08:52 -070088 private:
Darin Petkov633ac6f2011-07-08 13:56:13 -070089 friend class DeviceInfoTest;
Darin Petkove0a312e2011-07-20 13:45:28 -070090 friend class ModemTest;
91 friend class RTNLHandlerTest;
Darin Petkov633ac6f2011-07-08 13:56:13 -070092 friend struct DefaultSingletonTraits<RTNLHandler>;
Darin Petkovca432fc2011-07-08 15:56:57 -070093 FRIEND_TEST(RTNLListenerTest, NoRun);
94 FRIEND_TEST(RTNLListenerTest, Run);
Darin Petkov633ac6f2011-07-08 13:56:13 -070095
96 // Private to ensure that this behaves as a singleton.
97 RTNLHandler();
98 virtual ~RTNLHandler();
99
Paul Stewarta3c56f92011-05-26 07:08:52 -0700100 // Dispatches an rtnl message to all listeners
101 void DispatchEvent(int type, struct nlmsghdr *hdr);
102 // Send the next table-dump request to the kernel
103 void NextRequest(uint32_t seq);
104 // Parse an incoming rtnl message from the kernel
105 void ParseRTNL(InputData *data);
Paul Stewartc39f1132011-06-22 12:02:28 -0700106 bool AddressRequest(int interface_index, int cmd, int flags,
107 const IPConfig &config);
Paul Stewarta3c56f92011-05-26 07:08:52 -0700108
Darin Petkov633ac6f2011-07-08 13:56:13 -0700109 Sockets *sockets_;
Paul Stewarta3c56f92011-05-26 07:08:52 -0700110 bool in_request_;
111
112 int rtnl_socket_;
113 uint32_t request_flags_;
114 uint32_t request_sequence_;
115
116 std::vector<RTNLListener *> listeners_;
117 scoped_ptr<Callback1<InputData *>::Type> rtnl_callback_;
118 scoped_ptr<IOInputHandler> rtnl_handler_;
119
Paul Stewarta3c56f92011-05-26 07:08:52 -0700120 DISALLOW_COPY_AND_ASSIGN(RTNLHandler);
121};
122
123} // namespace shill
124
125#endif // SHILL_RTNL_HANDLER_