blob: 7209ae1ca5d9e96cb6e10dd205d9e53a8b429ceb [file] [log] [blame]
Wade Guthrie0d438532012-05-18 14:18:50 -07001// Copyright (c) 2012 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
Wade Guthriebee87c22013-03-06 11:00:46 -08005// This software provides an abstracted interface to the netlink socket
6// interface. In its current implementation it is used, primarily, to
7// communicate with the cfg80211 kernel module and mac80211 drivers:
Wade Guthrie0d438532012-05-18 14:18:50 -07008//
repo syncbcaa6942013-01-02 15:38:21 -08009// [shill]--[nl80211 library, libnl_genl/libnl libraries]
10// |
11// (netlink socket)
12// |
Wade Guthrie0d438532012-05-18 14:18:50 -070013// [cfg80211 kernel module]
repo syncbcaa6942013-01-02 15:38:21 -080014// |
15// [mac80211 drivers]
Wade Guthriebee87c22013-03-06 11:00:46 -080016//
17// In order to send a message and handle it's response, do the following:
18// - Create a handler (it'll want to verify that it's the kind of message you
19// want, cast it to the appropriate type, and get attributes from the cast
20// message):
21//
22// #include "nl80211_message.h"
23// class SomeClass {
24// static void MyMessageHandler(const NetlinkMessage &raw) {
25// if (raw.message_type() != ControlNetlinkMessage::kMessageType)
26// return;
27// const ControlNetlinkMessage *message =
28// reinterpret_cast<const ControlNetlinkMessage *>(&raw);
29// if (message.command() != NewFamilyMessage::kCommand)
30// return;
31// uint16_t my_attribute;
32// message->const_attributes()->GetU16AttributeValue(
33// CTRL_ATTR_FAMILY_ID, &my_attribute);
34// } // MyMessageHandler.
35// } // class SomeClass.
36//
37// - Instantiate a message:
38//
39// #include "nl80211_message.h"
40// GetFamilyMessage msg;
41//
Wade Guthrie2623f1a2013-05-14 15:14:54 -070042// - And set attributes:
Wade Guthriebee87c22013-03-06 11:00:46 -080043//
Wade Guthrie2623f1a2013-05-14 15:14:54 -070044// msg.attributes()->SetStringAttributeValue(CTRL_ATTR_FAMILY_NAME, "foo");
Wade Guthriebee87c22013-03-06 11:00:46 -080045//
46// - Then send the message, passing-in a closure to the handler you created:
47//
Wade Guthriebb9fca22013-04-10 17:21:42 -070048// NetlinkManager *netlink_manager = NetlinkManager::GetInstance();
49// netlink_manager->SendMessage(&msg, Bind(&SomeClass::MyMessageHandler));
Wade Guthriebee87c22013-03-06 11:00:46 -080050//
Wade Guthriebb9fca22013-04-10 17:21:42 -070051// NetlinkManager will then save your handler and send your message. When a
Wade Guthriebee87c22013-03-06 11:00:46 -080052// response to your message arrives, it'll call your handler.
53//
Wade Guthrie0d438532012-05-18 14:18:50 -070054
Wade Guthriebb9fca22013-04-10 17:21:42 -070055#ifndef SHILL_NETLINK_MANAGER_H_
56#define SHILL_NETLINK_MANAGER_H_
Wade Guthrie0d438532012-05-18 14:18:50 -070057
Wade Guthrieb1ec8602012-10-18 17:26:14 -070058#include <list>
Wade Guthrie0d438532012-05-18 14:18:50 -070059#include <map>
Wade Guthried6153612012-08-23 11:36:14 -070060#include <set>
Wade Guthrie0d438532012-05-18 14:18:50 -070061#include <string>
62
63#include <base/basictypes.h>
64#include <base/bind.h>
65#include <base/lazy_instance.h>
Wade Guthrieb9c3feb2013-04-25 16:31:19 -070066#include <base/memory/scoped_ptr.h>
67#include <gtest/gtest_prod.h> // for FRIEND_TEST
Wade Guthrie0d438532012-05-18 14:18:50 -070068
Wade Guthrie7347bf22013-04-30 11:21:51 -070069#include "shill/generic_netlink_message.h"
Wade Guthrieb9c3feb2013-04-25 16:31:19 -070070#include "shill/io_handler.h"
Wade Guthrie0ae4b8e2013-04-10 16:49:15 -070071#include "shill/netlink_message.h"
Wade Guthriefa2100e2013-05-15 10:11:22 -070072#include "shill/shill_time.h"
Wade Guthrie12f113a2013-03-12 17:15:46 -070073
Wade Guthrie89e6cb32013-03-07 08:03:45 -080074struct nlmsghdr;
Wade Guthrie0d438532012-05-18 14:18:50 -070075
76namespace shill {
77
Wade Guthrie7347bf22013-04-30 11:21:51 -070078class ControlNetlinkMessage;
repo syncbcaa6942013-01-02 15:38:21 -080079class Error;
Wade Guthrie89e6cb32013-03-07 08:03:45 -080080class EventDispatcher;
Liam McLoughlinf4baef22012-08-01 19:08:25 -070081struct InputData;
Wade Guthrie89e6cb32013-03-07 08:03:45 -080082class NetlinkSocket;
Wade Guthrie7347bf22013-04-30 11:21:51 -070083class Nl80211Message;
Wade Guthrie0d438532012-05-18 14:18:50 -070084
Wade Guthriebb9fca22013-04-10 17:21:42 -070085// NetlinkManager is a singleton that coordinates sending netlink messages to,
Wade Guthriebee87c22013-03-06 11:00:46 -080086// and receiving netlink messages from, the kernel. The first use of this is
87// to communicate between user-space and the cfg80211 module that manages wifi
Wade Guthriebb9fca22013-04-10 17:21:42 -070088// drivers. Bring NetlinkManager up as follows:
89// NetlinkManager *netlink_manager_ = NetlinkManager::GetInstance();
Wade Guthriebee87c22013-03-06 11:00:46 -080090// EventDispatcher dispatcher_;
Wade Guthriebb9fca22013-04-10 17:21:42 -070091// netlink_manager_->Init(); // Initialize the socket.
Wade Guthriebee87c22013-03-06 11:00:46 -080092// // Get message types for all dynamic message types.
93// Nl80211Message::SetMessageType(
Wade Guthriebb9fca22013-04-10 17:21:42 -070094// netlink_manager_->GetFamily(Nl80211Message::kMessageTypeString,
Wade Guthriebee87c22013-03-06 11:00:46 -080095// Bind(&Nl80211Message::CreateMessage)));
Wade Guthriebb9fca22013-04-10 17:21:42 -070096// netlink_manager_->Start(&dispatcher_);
97class NetlinkManager {
Wade Guthrie0d438532012-05-18 14:18:50 -070098 public:
Wade Guthrief48a1952013-03-04 17:33:47 -080099 typedef base::Callback<void(const NetlinkMessage &)> NetlinkMessageHandler;
Wade Guthrie7347bf22013-04-30 11:21:51 -0700100 typedef base::Callback<void(const ControlNetlinkMessage &)>
101 ControlNetlinkMessageHandler;
102 typedef base::Callback<void(const Nl80211Message &)> Nl80211MessageHandler;
103 // NetlinkAuxilliaryMessageHandler handles netlink error messages, things
104 // like the DoneMessage at the end of a multi-part message, and any errors
105 // discovered by |NetlinkManager| (which are passed as NULL pointers because
106 // there is no way to reserve a part of the ErrorAckMessage space for
107 // non-netlink errors).
108 typedef base::Callback<void(const NetlinkMessage *)>
109 NetlinkAuxilliaryMessageHandler;
110
111 // ResponseHandlers provide a polymorphic context for the base::Callback
112 // message handlers so that handlers for different types of messages can be
113 // kept in the same container (namely, |message_handlers_|).
114 class NetlinkResponseHandler :
115 public base::RefCounted<NetlinkResponseHandler> {
116 public:
117 explicit NetlinkResponseHandler(
118 const NetlinkAuxilliaryMessageHandler &error_handler);
119 virtual ~NetlinkResponseHandler();
120 // Calls wrapper-type-specific callback for |netlink_message|. Returns
121 // false if |netlink_message| is not the correct type. Calls callback
122 // (which is declared in the private area of derived classes) with
123 // properly cast version of |netlink_message|.
124 virtual bool HandleMessage(const NetlinkMessage &netlink_message) const = 0;
125 void HandleError(const NetlinkMessage *netlink_message) const;
126
127 protected:
128 NetlinkResponseHandler();
129
130 private:
131 NetlinkAuxilliaryMessageHandler error_handler_;
132
133 DISALLOW_COPY_AND_ASSIGN(NetlinkResponseHandler);
134 };
Wade Guthrie0d438532012-05-18 14:18:50 -0700135
Wade Guthriebee87c22013-03-06 11:00:46 -0800136 // Encapsulates all the different things we know about a specific message
Wade Guthrie0ae4b8e2013-04-10 16:49:15 -0700137 // type like its name, and its id.
Wade Guthriebee87c22013-03-06 11:00:46 -0800138 struct MessageType {
139 MessageType();
140
141 uint16_t family_id;
142
143 // Multicast groups supported by the family. The string and mapping to
144 // a group id are extracted from the CTRL_CMD_NEWFAMILY message.
145 std::map<std::string, uint32_t> groups;
Wade Guthrie0d438532012-05-18 14:18:50 -0700146 };
147
Wade Guthriebee87c22013-03-06 11:00:46 -0800148 // Various kinds of events to which we can subscribe (and receive) from
149 // cfg80211.
150 static const char kEventTypeConfig[];
151 static const char kEventTypeScan[];
152 static const char kEventTypeRegulatory[];
153 static const char kEventTypeMlme[];
154
Wade Guthriebb9fca22013-04-10 17:21:42 -0700155 // NetlinkManager is a singleton and this is the way to access it.
156 static NetlinkManager *GetInstance();
Wade Guthrie0d438532012-05-18 14:18:50 -0700157
Wade Guthriebb9fca22013-04-10 17:21:42 -0700158 // Performs non-trivial object initialization of the NetlinkManager singleton.
Wade Guthriebee87c22013-03-06 11:00:46 -0800159 bool Init();
Wade Guthrie0d438532012-05-18 14:18:50 -0700160
Wade Guthriebee87c22013-03-06 11:00:46 -0800161 // Passes the job of waiting for, and the subsequent reading from, the
162 // netlink socket to |dispatcher|.
163 void Start(EventDispatcher *dispatcher);
Wade Guthrie0d438532012-05-18 14:18:50 -0700164
Wade Guthriebee87c22013-03-06 11:00:46 -0800165 // The following methods deal with the network family table. This table
166 // associates netlink family names with family_ids (also called message
167 // types). Note that some families have static ids assigned to them but
168 // others require the kernel to resolve a string describing the family into
169 // a dynamically-determined id.
170
171 // Returns the family_id (message type) associated with |family_name|,
172 // calling the kernel if needed. Returns
173 // |NetlinkMessage::kIllegalMessageType| if the message type could not be
174 // determined. May block so |GetFamily| should be called before entering the
175 // event loop.
Wade Guthriefa2100e2013-05-15 10:11:22 -0700176 virtual uint16_t GetFamily(const std::string &family_name,
Wade Guthrie12f113a2013-03-12 17:15:46 -0700177 const NetlinkMessageFactory::FactoryMethod &message_factory);
Wade Guthriebee87c22013-03-06 11:00:46 -0800178
Wade Guthriebb9fca22013-04-10 17:21:42 -0700179 // Install a NetlinkManager NetlinkMessageHandler. The handler is a
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800180 // user-supplied object to be called by the system for user-bound messages
181 // that do not have a corresponding messaage-specific callback.
182 // |AddBroadcastHandler| should be called before |SubscribeToEvents| since
183 // the result of this call are used for that call.
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -0700184 virtual bool AddBroadcastHandler(
185 const NetlinkMessageHandler &message_handler);
Wade Guthrie0d438532012-05-18 14:18:50 -0700186
Wade Guthriebee87c22013-03-06 11:00:46 -0800187 // Uninstall a NetlinkMessage Handler.
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -0700188 virtual bool RemoveBroadcastHandler(
189 const NetlinkMessageHandler &message_handler);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700190
Wade Guthriebee87c22013-03-06 11:00:46 -0800191 // Determines whether a handler is in the list of broadcast handlers.
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800192 bool FindBroadcastHandler(const NetlinkMessageHandler &message_handler) const;
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700193
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800194 // Uninstall all broadcast netlink message handlers.
195 void ClearBroadcastHandlers();
Wade Guthrie0d438532012-05-18 14:18:50 -0700196
Wade Guthriebb9fca22013-04-10 17:21:42 -0700197 // Sends a netlink message to the kernel using the NetlinkManager socket after
Wade Guthriebee87c22013-03-06 11:00:46 -0800198 // installing a handler to deal with the kernel's response to the message.
Wade Guthrie5d53d492012-11-07 09:53:31 -0800199 // TODO(wdg): Eventually, this should also include a timeout and a callback
200 // to call in case of timeout.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700201 virtual bool SendControlMessage(
202 ControlNetlinkMessage *message,
203 const ControlNetlinkMessageHandler &message_handler,
204 const NetlinkAuxilliaryMessageHandler &error_handler);
205 virtual bool SendNl80211Message(
206 Nl80211Message *message,
207 const Nl80211MessageHandler &message_handler,
208 const NetlinkAuxilliaryMessageHandler &error_handler);
209
210 // Generic erroneous message handler everyone can use.
211 static void OnNetlinkMessageError(const NetlinkMessage *raw_message);
Wade Guthrie5d53d492012-11-07 09:53:31 -0800212
Wade Guthriebee87c22013-03-06 11:00:46 -0800213 // Uninstall the handler for a specific netlink message.
Wade Guthrief48a1952013-03-04 17:33:47 -0800214 bool RemoveMessageHandler(const NetlinkMessage &message);
Wade Guthrie0d438532012-05-18 14:18:50 -0700215
Wade Guthried6153612012-08-23 11:36:14 -0700216 // Sign-up to receive and log multicast events of a specific type (once wifi
217 // is up).
Wade Guthrie5a4e2ef2013-04-30 12:51:39 -0700218 virtual bool SubscribeToEvents(const std::string &family,
219 const std::string &group);
Wade Guthried6153612012-08-23 11:36:14 -0700220
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800221 // Gets the next sequence number for a NetlinkMessage to be sent over
Wade Guthriebb9fca22013-04-10 17:21:42 -0700222 // NetlinkManager's netlink socket.
Wade Guthriebdcdaa72013-03-04 12:47:12 -0800223 uint32_t GetSequenceNumber();
224
Wade Guthrie0d438532012-05-18 14:18:50 -0700225 protected:
Wade Guthriebb9fca22013-04-10 17:21:42 -0700226 friend struct base::DefaultLazyInstanceTraits<NetlinkManager>;
Wade Guthrie0d438532012-05-18 14:18:50 -0700227
Wade Guthriebb9fca22013-04-10 17:21:42 -0700228 explicit NetlinkManager();
Wade Guthrie0d438532012-05-18 14:18:50 -0700229
230 private:
Wade Guthriebb9fca22013-04-10 17:21:42 -0700231 friend class NetlinkManagerTest;
Wade Guthrie12f113a2013-03-12 17:15:46 -0700232 friend class NetlinkMessageTest;
Darin Petkovd5818382013-01-28 16:27:07 +0100233 friend class ShillDaemonTest;
Wade Guthriebb9fca22013-04-10 17:21:42 -0700234 FRIEND_TEST(NetlinkManagerTest, AddLinkTest);
Wade Guthriebbe59f72013-05-21 08:45:39 -0700235 FRIEND_TEST(NetlinkManagerTest, BroadcastHandler);
Wade Guthriefa2100e2013-05-15 10:11:22 -0700236 FRIEND_TEST(NetlinkManagerTest, GetFamilyOneInterstitialMessage);
237 FRIEND_TEST(NetlinkManagerTest, GetFamilyTimeout);
Wade Guthriebbe59f72013-05-21 08:45:39 -0700238 FRIEND_TEST(NetlinkManagerTest, MessageHandler);
239 FRIEND_TEST(NetlinkManagerTest, MultipartMessageHandler);
Wade Guthrie12f113a2013-03-12 17:15:46 -0700240 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_TRIGGER_SCAN);
241 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_NEW_SCAN_RESULTS);
242 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_NEW_STATION);
243 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_AUTHENTICATE);
244 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_ASSOCIATE);
245 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_CONNECT);
246 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_DEAUTHENTICATE);
247 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_DISCONNECT);
248 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_NOTIFY_CQM);
249 FRIEND_TEST(NetlinkMessageTest, Parse_NL80211_CMD_DISASSOCIATE);
250
Wade Guthrie7347bf22013-04-30 11:21:51 -0700251 typedef scoped_refptr<NetlinkResponseHandler> NetlinkResponseHandlerRefPtr;
Wade Guthrie0d438532012-05-18 14:18:50 -0700252
Wade Guthriebee87c22013-03-06 11:00:46 -0800253 static const long kMaximumNewFamilyWaitSeconds;
254 static const long kMaximumNewFamilyWaitMicroSeconds;
255
256 // Returns the file descriptor of socket used to read wifi data.
Wade Guthrie89e6cb32013-03-07 08:03:45 -0800257 int file_descriptor() const;
Wade Guthried6153612012-08-23 11:36:14 -0700258
Wade Guthrie0d438532012-05-18 14:18:50 -0700259 // EventDispatcher calls this when data is available on our socket. This
repo syncbcaa6942013-01-02 15:38:21 -0800260 // method passes each, individual, message in the input to
Wade Guthriebee87c22013-03-06 11:00:46 -0800261 // |OnNlMessageReceived|. Each part of a multipart message gets handled,
262 // individually, by this method.
repo syncbcaa6942013-01-02 15:38:21 -0800263 void OnRawNlMessageReceived(InputData *data);
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700264
265 // This method processes a message from |OnRawNlMessageReceived| by passing
Wade Guthriebb9fca22013-04-10 17:21:42 -0700266 // the message to either the NetlinkManager callback that matches the sequence
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700267 // number of the message or, if there isn't one, to all of the default
Wade Guthriebb9fca22013-04-10 17:21:42 -0700268 // NetlinkManager callbacks in |broadcast_handlers_|.
repo syncbcaa6942013-01-02 15:38:21 -0800269 void OnNlMessageReceived(nlmsghdr *msg);
270
271 // Called by InputHandler on exceptional events.
272 void OnReadError(const Error &error);
Wade Guthrie0d438532012-05-18 14:18:50 -0700273
Wade Guthriebee87c22013-03-06 11:00:46 -0800274 // Just for tests, this method turns off WiFi and clears the subscribed
275 // events list. If |full| is true, also clears state set by Init.
Darin Petkovd5818382013-01-28 16:27:07 +0100276 void Reset(bool full);
Wade Guthried6153612012-08-23 11:36:14 -0700277
Wade Guthriebee87c22013-03-06 11:00:46 -0800278 // Handles a CTRL_CMD_NEWFAMILY message from the kernel.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700279 void OnNewFamilyMessage(const ControlNetlinkMessage &message);
280
281 // Sends a netlink message to the kernel using the NetlinkManager socket after
282 // installing a handler to deal with the kernel's response to the message.
283 // Adds a serial number to |message| before it is sent.
284 bool SendMessageInternal(
285 NetlinkMessage *message,
286 NetlinkResponseHandler *message_wrapper); // Passes ownership.
Wade Guthriebee87c22013-03-06 11:00:46 -0800287
Wade Guthriebb9fca22013-04-10 17:21:42 -0700288 // NetlinkManager Handlers, OnRawNlMessageReceived invokes each of these
Wade Guthrieb1ec8602012-10-18 17:26:14 -0700289 // User-supplied callback object when _it_ gets called to read libnl data.
Wade Guthrie71cb0a72013-02-27 10:27:18 -0800290 std::list<NetlinkMessageHandler> broadcast_handlers_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700291
Wade Guthrie5d3d6de2012-11-02 11:08:34 -0700292 // Message-specific callbacks, mapped by message ID.
Wade Guthrie7347bf22013-04-30 11:21:51 -0700293 std::map<uint32_t, NetlinkResponseHandlerRefPtr> message_handlers_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700294
Wade Guthrie0d438532012-05-18 14:18:50 -0700295 // Hooks needed to be called by shill's EventDispatcher.
296 EventDispatcher *dispatcher_;
Wade Guthriebb9fca22013-04-10 17:21:42 -0700297 base::WeakPtrFactory<NetlinkManager> weak_ptr_factory_;
repo syncbcaa6942013-01-02 15:38:21 -0800298 base::Callback<void(InputData *)> dispatcher_callback_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700299 scoped_ptr<IOHandler> dispatcher_handler_;
300
Wade Guthriecc53f232013-03-05 13:22:23 -0800301 NetlinkSocket *sock_;
Wade Guthriebee87c22013-03-06 11:00:46 -0800302 std::map<const std::string, MessageType> message_types_;
Wade Guthrie12f113a2013-03-12 17:15:46 -0700303 NetlinkMessageFactory message_factory_;
Wade Guthriefa2100e2013-05-15 10:11:22 -0700304 Time *time_;
Wade Guthrie0d438532012-05-18 14:18:50 -0700305
Wade Guthriebb9fca22013-04-10 17:21:42 -0700306 DISALLOW_COPY_AND_ASSIGN(NetlinkManager);
Wade Guthrie0d438532012-05-18 14:18:50 -0700307};
308
Wade Guthrie0d438532012-05-18 14:18:50 -0700309} // namespace shill
310
Wade Guthriebb9fca22013-04-10 17:21:42 -0700311#endif // SHILL_NETLINK_MANAGER_H_