2 * Copyright (C) 2016 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "net/netlink_manager.h"
22 #include <linux/netlink.h>
23 #include <linux/nl80211.h>
25 #include <sys/socket.h>
27 #include <android-base/logging.h>
28 #include <utils/Timers.h>
30 #include "net/mlme_event.h"
31 #include "net/mlme_event_handler.h"
32 #include "net/nl80211_attribute.h"
33 #include "net/nl80211_packet.h"
35 using android::base::unique_fd;
36 using std::placeholders::_1;
38 using std::unique_ptr;
46 // netlink.h suggests NLMSG_GOODSIZE to be at most 8192 bytes.
47 constexpr int kReceiveBufferSize = 8 * 1024;
48 constexpr uint32_t kBroadcastSequenceNumber = 0;
49 constexpr int kMaximumNetlinkMessageWaitMilliSeconds = 300;
50 uint8_t ReceiveBuffer[kReceiveBufferSize];
52 void AppendPacket(vector<unique_ptr<const NL80211Packet>>* vec,
53 unique_ptr<const NL80211Packet> packet) {
54 vec->push_back(std::move(packet));
59 NetlinkManager::NetlinkManager(EventLoop* event_loop)
61 event_loop_(event_loop),
65 NetlinkManager::~NetlinkManager() {
68 uint32_t NetlinkManager::GetSequenceNumber() {
69 if (++sequence_number_ == kBroadcastSequenceNumber) {
72 return sequence_number_;
75 void NetlinkManager::ReceivePacketAndRunHandler(int fd) {
76 ssize_t len = read(fd, ReceiveBuffer, kReceiveBufferSize);
78 LOG(ERROR) << "Failed to read packet from buffer";
84 // There might be multiple message in one datagram payload.
85 uint8_t* ptr = ReceiveBuffer;
86 while (ptr < ReceiveBuffer + len) {
87 // peek at the header.
88 if (ptr + sizeof(nlmsghdr) > ReceiveBuffer + len) {
89 LOG(ERROR) << "payload is broken.";
92 const nlmsghdr* nl_header = reinterpret_cast<const nlmsghdr*>(ptr);
93 unique_ptr<NL80211Packet> packet(
94 new NL80211Packet(vector<uint8_t>(ptr, ptr + nl_header->nlmsg_len)));
95 ptr += nl_header->nlmsg_len;
96 if (!packet->IsValid()) {
97 LOG(ERROR) << "Receive invalid packet";
100 // Some document says message from kernel should have port id equal 0.
101 // However in practice this is not always true so we don't check that.
103 uint32_t sequence_number = packet->GetMessageSequence();
105 // Handle multicasts.
106 if (sequence_number == kBroadcastSequenceNumber) {
107 BroadcastHandler(std::move(packet));
111 auto itr = message_handlers_.find(sequence_number);
112 // There is no handler for this sequence number.
113 if (itr == message_handlers_.end()) {
114 LOG(WARNING) << "No handler for message: " << sequence_number;
117 // A multipart message is terminated by NLMSG_DONE.
118 // In this case we don't need to run the handler.
119 // NLMSG_NOOP means no operation, message must be discarded.
120 uint32_t message_type = packet->GetMessageType();
121 if (message_type == NLMSG_DONE || message_type == NLMSG_NOOP) {
122 message_handlers_.erase(itr);
125 if (message_type == NLMSG_OVERRUN) {
126 LOG(ERROR) << "Get message overrun notification";
127 message_handlers_.erase(itr);
131 // In case we receive a NLMSG_ERROR message:
132 // NLMSG_ERROR could be either an error or an ACK.
133 // It is an ACK message only when error code field is set to 0.
134 // An ACK could be return when we explicitly request that with NLM_F_ACK.
135 // An ERROR could be received on NLM_F_ACK or other failure cases.
136 // We should still run handler in this case, leaving it for the caller
137 // to decide what to do with the packet.
139 bool is_multi = packet->IsMulti();
141 itr->second(std::move(packet));
142 // Remove handler after processing.
144 message_handlers_.erase(itr);
149 void NetlinkManager::OnNewFamily(unique_ptr<const NL80211Packet> packet) {
150 if (packet->GetMessageType() != GENL_ID_CTRL) {
151 LOG(ERROR) << "Wrong message type for new family message";
154 if (packet->GetCommand() != CTRL_CMD_NEWFAMILY) {
155 LOG(ERROR) << "Wrong command for new family message";
159 if (!packet->GetAttributeValue(CTRL_ATTR_FAMILY_ID, &family_id)) {
160 LOG(ERROR) << "Failed to get family id";
164 if (!packet->GetAttributeValue(CTRL_ATTR_FAMILY_NAME, &family_name)) {
165 LOG(ERROR) << "Failed to get family name";
168 if (family_name != NL80211_GENL_NAME) {
169 LOG(WARNING) << "Ignoring none nl80211 netlink families";
171 MessageType nl80211_type(family_id);
172 message_types_[family_name] = nl80211_type;
173 // Exract multicast groups.
174 NL80211NestedAttr multicast_groups(0);
175 if (packet->GetAttribute(CTRL_ATTR_MCAST_GROUPS, &multicast_groups)) {
176 vector<NL80211NestedAttr> groups;
177 if (!multicast_groups.GetListOfNestedAttributes(&groups)) {
180 for (auto& group : groups) {
183 if (!group.GetAttributeValue(CTRL_ATTR_MCAST_GRP_NAME, &group_name)) {
184 LOG(ERROR) << "Failed to get group name";
186 if (!group.GetAttributeValue(CTRL_ATTR_MCAST_GRP_ID, &group_id)) {
187 LOG(ERROR) << "Failed to get group id";
189 message_types_[family_name].groups[group_name] = group_id;
194 bool NetlinkManager::Start() {
196 LOG(DEBUG) << "NetlinkManager is already started";
199 bool setup_rt = SetupSocket(&sync_netlink_fd_);
201 LOG(ERROR) << "Failed to setup synchronous netlink socket";
205 setup_rt = SetupSocket(&async_netlink_fd_);
207 LOG(ERROR) << "Failed to setup asynchronous netlink socket";
211 // Request family id for nl80211 messages.
212 if (!DiscoverFamilyId()) {
216 if (!WatchSocket(&async_netlink_fd_)) {
219 // TODO(nywang): Uncomment the following lines to enable wificond scan
220 // result monitoring, after we finish the integration.
221 // if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_SCAN)) {
224 if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_MLME)) {
232 bool NetlinkManager::IsStarted() const {
236 bool NetlinkManager::RegisterHandlerAndSendMessage(
237 const NL80211Packet& packet,
238 std::function<void(unique_ptr<const NL80211Packet>)> handler) {
239 if (packet.IsDump()) {
240 LOG(ERROR) << "Do not use asynchronous interface for dump request !";
243 if (!SendMessageInternal(packet, async_netlink_fd_.get())) {
246 message_handlers_[packet.GetMessageSequence()] = handler;
250 bool NetlinkManager::SendMessageAndGetResponses(
251 const NL80211Packet& packet,
252 vector<unique_ptr<const NL80211Packet>>* response) {
253 if (!SendMessageInternal(packet, sync_netlink_fd_.get())) {
256 // Polling netlink socket, waiting for GetFamily reply.
257 struct pollfd netlink_output;
258 memset(&netlink_output, 0, sizeof(netlink_output));
259 netlink_output.fd = sync_netlink_fd_.get();
260 netlink_output.events = POLLIN;
262 uint32_t sequence = packet.GetMessageSequence();
264 int time_remaining = kMaximumNetlinkMessageWaitMilliSeconds;
265 // Multipart messages may come with seperated datagrams, ending with a
266 // NLMSG_DONE message.
267 // ReceivePacketAndRunHandler() will remove the handler after receiving a
268 // NLMSG_DONE message.
269 message_handlers_[sequence] = std::bind(AppendPacket, response, _1);
271 while (time_remaining > 0 &&
272 message_handlers_.find(sequence) != message_handlers_.end()) {
273 nsecs_t interval = systemTime(SYSTEM_TIME_MONOTONIC);
274 int poll_return = poll(&netlink_output,
278 if (poll_return == 0) {
279 LOG(ERROR) << "Failed to poll netlink fd: time out ";
280 message_handlers_.erase(sequence);
282 } else if (poll_return == -1) {
283 LOG(ERROR) << "Failed to poll netlink fd: " << strerror(errno);
284 message_handlers_.erase(sequence);
287 ReceivePacketAndRunHandler(sync_netlink_fd_.get());
288 interval = systemTime(SYSTEM_TIME_MONOTONIC) - interval;
289 time_remaining -= static_cast<int>(ns2ms(interval));
291 if (time_remaining <= 0) {
292 LOG(ERROR) << "Timeout waiting for netlink reply messages";
293 message_handlers_.erase(sequence);
299 bool NetlinkManager::SendMessageAndGetSingleResponse(
300 const NL80211Packet& packet,
301 unique_ptr<const NL80211Packet>* response) {
302 unique_ptr<const NL80211Packet> response_or_error;
303 if (!SendMessageAndGetSingleResponseOrError(packet, &response_or_error)) {
306 if (response_or_error->GetMessageType() == NLMSG_ERROR) {
307 // We use ERROR because we are not expecting to receive a ACK here.
308 // In that case the caller should use |SendMessageAndGetAckOrError|.
309 LOG(ERROR) << "Received error message: "
310 << strerror(response_or_error->GetErrorCode());
313 *response = std::move(response_or_error);
317 bool NetlinkManager::SendMessageAndGetSingleResponseOrError(
318 const NL80211Packet& packet,
319 unique_ptr<const NL80211Packet>* response) {
320 vector<unique_ptr<const NL80211Packet>> response_vec;
321 if (!SendMessageAndGetResponses(packet, &response_vec)) {
324 if (response_vec.size() != 1) {
325 LOG(ERROR) << "Unexpected response size: " << response_vec.size();
329 *response = std::move(response_vec[0]);
333 bool NetlinkManager::SendMessageAndGetAckOrError(const NL80211Packet& packet,
335 unique_ptr<const NL80211Packet> response;
336 if (!SendMessageAndGetSingleResponseOrError(packet, &response)) {
339 uint16_t type = response->GetMessageType();
340 if (type != NLMSG_ERROR) {
341 LOG(ERROR) << "Receive unexpected message type :" << type;
345 *error_code = response->GetErrorCode();
349 bool NetlinkManager::SendMessageAndGetAck(const NL80211Packet& packet) {
351 if (!SendMessageAndGetAckOrError(packet, &error_code)) {
354 if (error_code != 0) {
355 LOG(ERROR) << "Received error messsage: " << strerror(error_code);
362 bool NetlinkManager::SendMessageInternal(const NL80211Packet& packet, int fd) {
363 const vector<uint8_t>& data = packet.GetConstData();
365 TEMP_FAILURE_RETRY(send(fd, data.data(), data.size(), 0));
366 if (bytes_sent == -1) {
367 LOG(ERROR) << "Failed to send netlink message: " << strerror(errno);
373 bool NetlinkManager::SetupSocket(unique_fd* netlink_fd) {
374 struct sockaddr_nl nladdr;
376 memset(&nladdr, 0, sizeof(nladdr));
377 nladdr.nl_family = AF_NETLINK;
380 socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_GENERIC));
381 if (netlink_fd->get() < 0) {
382 LOG(ERROR) << "Failed to create netlink socket: " << strerror(errno);
385 // Set maximum receive buffer size.
386 // Datagram which is larger than this size will be discarded.
387 if (setsockopt(netlink_fd->get(),
391 sizeof(kReceiveBufferSize)) < 0) {
392 LOG(ERROR) << "Failed to set uevent socket SO_RCVBUFFORCE option: " << strerror(errno);
395 if (bind(netlink_fd->get(),
396 reinterpret_cast<struct sockaddr*>(&nladdr),
397 sizeof(nladdr)) < 0) {
398 LOG(ERROR) << "Failed to bind netlink socket: " << strerror(errno);
404 bool NetlinkManager::WatchSocket(unique_fd* netlink_fd) {
406 bool watch_fd_rt = event_loop_->WatchFileDescriptor(
408 EventLoop::kModeInput,
409 std::bind(&NetlinkManager::ReceivePacketAndRunHandler, this, _1));
411 LOG(ERROR) << "Failed to watch fd: " << netlink_fd->get();
417 uint16_t NetlinkManager::GetFamilyId() {
418 return message_types_[NL80211_GENL_NAME].family_id;
421 bool NetlinkManager::DiscoverFamilyId() {
422 NL80211Packet get_family_request(GENL_ID_CTRL,
426 NL80211Attr<string> family_name(CTRL_ATTR_FAMILY_NAME, NL80211_GENL_NAME);
427 get_family_request.AddAttribute(family_name);
428 unique_ptr<const NL80211Packet> response;
429 if (!SendMessageAndGetSingleResponse(get_family_request, &response)) {
430 LOG(ERROR) << "Failed to get NL80211 family info";
433 OnNewFamily(std::move(response));
434 if (message_types_.find(NL80211_GENL_NAME) == message_types_.end()) {
435 LOG(ERROR) << "Failed to get NL80211 family id";
441 bool NetlinkManager::SubscribeToEvents(const string& group) {
442 auto groups = message_types_[NL80211_GENL_NAME].groups;
443 if (groups.find(group) == groups.end()) {
444 LOG(ERROR) << "Failed to subscribe: group " << group << " doesn't exist";
447 uint32_t group_id = groups[group];
448 int err = setsockopt(async_netlink_fd_.get(),
450 NETLINK_ADD_MEMBERSHIP,
454 LOG(ERROR) << "Failed to setsockopt: " << strerror(errno);
460 void NetlinkManager::BroadcastHandler(unique_ptr<const NL80211Packet> packet) {
461 if (packet->GetMessageType() != GetFamilyId()) {
462 LOG(ERROR) << "Wrong family id for multicast message";
465 uint32_t command = packet->GetCommand();
467 if (command == NL80211_CMD_NEW_SCAN_RESULTS ||
468 // Scan was aborted, for unspecified reasons.partial scan results may be
470 command == NL80211_CMD_SCAN_ABORTED) {
471 OnScanResultsReady(std::move(packet));
475 if (command == NL80211_CMD_SCHED_SCAN_RESULTS) {
476 OnSchedScanResultsReady(std::move(packet));
481 // Driver which supports SME uses both NL80211_CMD_AUTHENTICATE and
482 // NL80211_CMD_ASSOCIATE, otherwise it uses NL80211_CMD_CONNECT
483 // to notify a combination of authentication and association processses.
484 // Currently we monitor CONNECT/ASSOCIATE/ROAM event for up-to-date
485 // frequency and bssid.
486 // TODO(nywang): Handle other MLME events, which help us track the
487 // connection state better.
488 if (command == NL80211_CMD_CONNECT ||
489 command == NL80211_CMD_ASSOCIATE ||
490 command == NL80211_CMD_ROAM) {
491 OnMlmeEvent(std::move(packet));
496 void NetlinkManager::OnMlmeEvent(unique_ptr<const NL80211Packet> packet) {
499 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
500 LOG(ERROR) << "Failed to get interface index from a MLME event message";
503 auto handler = on_mlme_event_handler_.find(if_index);
504 if (handler == on_mlme_event_handler_.end()) {
505 LOG(DEBUG) << "No handler for mlme event from interface"
506 << " with index: " << if_index;
509 uint32_t command = packet->GetCommand();
510 if (command == NL80211_CMD_CONNECT) {
511 auto event = MlmeConnectEvent::InitFromPacket(packet.get());
512 if (event != nullptr) {
513 handler->second->OnConnect(std::move(event));
517 if (command == NL80211_CMD_ASSOCIATE) {
518 auto event = MlmeAssociateEvent::InitFromPacket(packet.get());
519 if (event != nullptr) {
520 handler->second->OnAssociate(std::move(event));
524 if (command == NL80211_CMD_ROAM) {
525 auto event = MlmeRoamEvent::InitFromPacket(packet.get());
526 if (event != nullptr) {
527 handler->second->OnRoam(std::move(event));
533 void NetlinkManager::OnSchedScanResultsReady(unique_ptr<const NL80211Packet> packet) {
535 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
536 LOG(ERROR) << "Failed to get interface index from scan result notification";
540 auto handler = on_sched_scan_result_ready_handler_.find(if_index);
541 if (handler == on_sched_scan_result_ready_handler_.end()) {
542 LOG(DEBUG) << "No handler for scheduled scan result notification from"
543 << " interface with index: " << if_index;
546 // Run scan result notification handler.
547 handler->second(if_index);
550 void NetlinkManager::OnScanResultsReady(unique_ptr<const NL80211Packet> packet) {
552 if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
553 LOG(ERROR) << "Failed to get interface index from scan result notification";
556 bool aborted = false;
557 if (packet->GetCommand() == NL80211_CMD_SCAN_ABORTED) {
561 auto handler = on_scan_result_ready_handler_.find(if_index);
562 if (handler == on_scan_result_ready_handler_.end()) {
563 LOG(DEBUG) << "No handler for scan result notification from interface"
564 << " with index: " << if_index;
568 vector<vector<uint8_t>> ssids;
569 NL80211NestedAttr ssids_attr(0);
570 if (!packet->GetAttribute(NL80211_ATTR_SCAN_SSIDS, &ssids_attr)) {
572 LOG(WARNING) << "Failed to get scan ssids from scan result notification";
575 if (!ssids_attr.GetListOfAttributeValues(&ssids)) {
579 vector<uint32_t> freqs;
580 NL80211NestedAttr freqs_attr(0);
581 if (!packet->GetAttribute(NL80211_ATTR_SCAN_FREQUENCIES, &freqs_attr)) {
583 LOG(WARNING) << "Failed to get scan freqs from scan result notification";
586 if (!freqs_attr.GetListOfAttributeValues(&freqs)) {
590 // Run scan result notification handler.
591 handler->second(if_index, aborted, ssids, freqs);
594 void NetlinkManager::SubscribeScanResultNotification(
595 uint32_t interface_index,
596 OnScanResultsReadyHandler handler) {
597 on_scan_result_ready_handler_[interface_index] = handler;
600 void NetlinkManager::UnsubscribeScanResultNotification(
601 uint32_t interface_index) {
602 on_scan_result_ready_handler_.erase(interface_index);
605 void NetlinkManager::SubscribeMlmeEvent(uint32_t interface_index,
606 MlmeEventHandler* handler) {
607 on_mlme_event_handler_[interface_index] = handler;
610 void NetlinkManager::UnsubscribeMlmeEvent(uint32_t interface_index) {
611 on_mlme_event_handler_.erase(interface_index);
614 void NetlinkManager::SubscribeSchedScanResultNotification(
615 uint32_t interface_index,
616 OnSchedScanResultsReadyHandler handler) {
617 on_sched_scan_result_ready_handler_[interface_index] = handler;
620 void NetlinkManager::UnsubscribeSchedScanResultNotification(
621 uint32_t interface_index) {
622 on_sched_scan_result_ready_handler_.erase(interface_index);
625 } // namespace wificond
626 } // namespace android