OSDN Git Service

Monitor mlme event for wificond
[android-x86/system-connectivity-wificond.git] / net / netlink_manager.cpp
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "net/netlink_manager.h"
18
19 #include <string>
20 #include <vector>
21
22 #include <linux/netlink.h>
23 #include <linux/nl80211.h>
24 #include <poll.h>
25 #include <sys/socket.h>
26
27 #include <android-base/logging.h>
28 #include <utils/Timers.h>
29
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"
34
35 using android::base::unique_fd;
36 using std::placeholders::_1;
37 using std::string;
38 using std::unique_ptr;
39 using std::vector;
40
41 namespace android {
42 namespace wificond {
43
44 namespace {
45
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];
51
52 void AppendPacket(vector<unique_ptr<const NL80211Packet>>* vec,
53                   unique_ptr<const NL80211Packet> packet) {
54   vec->push_back(std::move(packet));
55 }
56
57 }
58
59 NetlinkManager::NetlinkManager(EventLoop* event_loop)
60     : started_(false),
61       event_loop_(event_loop),
62       sequence_number_(0) {
63 }
64
65 NetlinkManager::~NetlinkManager() {
66 }
67
68 uint32_t NetlinkManager::GetSequenceNumber() {
69   if (++sequence_number_ == kBroadcastSequenceNumber) {
70     ++sequence_number_;
71   }
72   return sequence_number_;
73 }
74
75 void NetlinkManager::ReceivePacketAndRunHandler(int fd) {
76   ssize_t len = read(fd, ReceiveBuffer, kReceiveBufferSize);
77   if (len == -1) {
78     LOG(ERROR) << "Failed to read packet from buffer";
79     return;
80   }
81   if (len == 0) {
82     return;
83   }
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.";
90       return;
91     }
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";
98       return;
99     }
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.
102
103     uint32_t sequence_number = packet->GetMessageSequence();
104
105     // Handle multicasts.
106     if (sequence_number == kBroadcastSequenceNumber) {
107       BroadcastHandler(std::move(packet));
108       continue;
109     }
110
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;
115       return;
116     }
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);
123       return;
124     }
125     if (message_type == NLMSG_OVERRUN) {
126       LOG(ERROR) << "Get message overrun notification";
127       message_handlers_.erase(itr);
128       return;
129     }
130
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.
138
139     bool is_multi = packet->IsMulti();
140     // Run the handler.
141     itr->second(std::move(packet));
142     // Remove handler after processing.
143     if (!is_multi) {
144       message_handlers_.erase(itr);
145     }
146   }
147 }
148
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";
152     return;
153   }
154   if (packet->GetCommand() != CTRL_CMD_NEWFAMILY) {
155     LOG(ERROR) << "Wrong command for new family message";
156     return;
157   }
158   uint16_t family_id;
159   if (!packet->GetAttributeValue(CTRL_ATTR_FAMILY_ID, &family_id)) {
160     LOG(ERROR) << "Failed to get family id";
161     return;
162   }
163   string family_name;
164   if (!packet->GetAttributeValue(CTRL_ATTR_FAMILY_NAME, &family_name)) {
165     LOG(ERROR) << "Failed to get family name";
166     return;
167   }
168   if (family_name != NL80211_GENL_NAME) {
169     LOG(WARNING) << "Ignoring none nl80211 netlink families";
170   }
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)) {
178       return;
179     }
180     for (auto& group : groups) {
181       string group_name;
182       uint32_t group_id;
183       if (!group.GetAttributeValue(CTRL_ATTR_MCAST_GRP_NAME, &group_name)) {
184         LOG(ERROR) << "Failed to get group name";
185       }
186       if (!group.GetAttributeValue(CTRL_ATTR_MCAST_GRP_ID, &group_id)) {
187         LOG(ERROR) << "Failed to get group id";
188       }
189       message_types_[family_name].groups[group_name] = group_id;
190     }
191   }
192 }
193
194 bool NetlinkManager::Start() {
195   if (started_) {
196     LOG(DEBUG) << "NetlinkManager is already started";
197     return true;
198   }
199   bool setup_rt = SetupSocket(&sync_netlink_fd_);
200   if (!setup_rt) {
201     LOG(ERROR) << "Failed to setup synchronous netlink socket";
202     return false;
203   }
204
205   setup_rt = SetupSocket(&async_netlink_fd_);
206   if (!setup_rt) {
207     LOG(ERROR) << "Failed to setup asynchronous netlink socket";
208     return false;
209   }
210
211   // Request family id for nl80211 messages.
212   if (!DiscoverFamilyId()) {
213     return false;
214   }
215   // Watch socket.
216   if (!WatchSocket(&async_netlink_fd_)) {
217     return false;
218   }
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)) {
222   //    return false;
223   //  }
224   if (!SubscribeToEvents(NL80211_MULTICAST_GROUP_MLME)) {
225     return false;
226   }
227
228   started_ = true;
229   return true;
230 }
231
232 bool NetlinkManager::IsStarted() const {
233   return started_;
234 }
235
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 !";
241     return false;
242   }
243   if (!SendMessageInternal(packet, async_netlink_fd_.get())) {
244     return false;
245   }
246   message_handlers_[packet.GetMessageSequence()] = handler;
247   return true;
248 }
249
250 bool NetlinkManager::SendMessageAndGetResponses(
251     const NL80211Packet& packet,
252     vector<unique_ptr<const NL80211Packet>>* response) {
253   if (!SendMessageInternal(packet, sync_netlink_fd_.get())) {
254     return false;
255   }
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;
261
262   uint32_t sequence = packet.GetMessageSequence();
263
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);
270
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,
275                            1,
276                            time_remaining);
277
278     if (poll_return == 0) {
279       LOG(ERROR) << "Failed to poll netlink fd: time out ";
280       message_handlers_.erase(sequence);
281       return false;
282     } else if (poll_return == -1) {
283       LOG(ERROR) << "Failed to poll netlink fd: " << strerror(errno);
284       message_handlers_.erase(sequence);
285       return false;
286     }
287     ReceivePacketAndRunHandler(sync_netlink_fd_.get());
288     interval = systemTime(SYSTEM_TIME_MONOTONIC) - interval;
289     time_remaining -= static_cast<int>(ns2ms(interval));
290   }
291   if (time_remaining <= 0) {
292     LOG(ERROR) << "Timeout waiting for netlink reply messages";
293     message_handlers_.erase(sequence);
294     return false;
295   }
296   return true;
297 }
298
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)) {
304     return false;
305   }
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());
311     return false;
312   }
313   *response = std::move(response_or_error);
314   return true;
315 }
316
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)) {
322     return false;
323   }
324   if (response_vec.size() != 1) {
325     LOG(ERROR) << "Unexpected response size: " << response_vec.size();
326     return false;
327   }
328
329   *response = std::move(response_vec[0]);
330   return true;
331 }
332
333 bool NetlinkManager::SendMessageAndGetAckOrError(const NL80211Packet& packet,
334                                                  int* error_code) {
335   unique_ptr<const NL80211Packet> response;
336   if (!SendMessageAndGetSingleResponseOrError(packet, &response)) {
337     return false;
338   }
339   uint16_t type = response->GetMessageType();
340   if (type != NLMSG_ERROR) {
341     LOG(ERROR) << "Receive unexpected message type :" << type;
342     return false;
343   }
344
345   *error_code = response->GetErrorCode();
346   return true;
347 }
348
349 bool NetlinkManager::SendMessageAndGetAck(const NL80211Packet& packet) {
350   int error_code;
351   if (!SendMessageAndGetAckOrError(packet, &error_code)) {
352     return false;
353   }
354   if (error_code != 0) {
355     LOG(ERROR) << "Received error messsage: " << strerror(error_code);
356     return false;
357   }
358
359   return true;
360 }
361
362 bool NetlinkManager::SendMessageInternal(const NL80211Packet& packet, int fd) {
363   const vector<uint8_t>& data = packet.GetConstData();
364   ssize_t bytes_sent =
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);
368     return false;
369   }
370   return true;
371 }
372
373 bool NetlinkManager::SetupSocket(unique_fd* netlink_fd) {
374   struct sockaddr_nl nladdr;
375
376   memset(&nladdr, 0, sizeof(nladdr));
377   nladdr.nl_family = AF_NETLINK;
378
379   netlink_fd->reset(
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);
383     return false;
384   }
385   // Set maximum receive buffer size.
386   // Datagram which is larger than this size will be discarded.
387   if (setsockopt(netlink_fd->get(),
388                  SOL_SOCKET,
389                  SO_RCVBUFFORCE,
390                  &kReceiveBufferSize,
391                  sizeof(kReceiveBufferSize)) < 0) {
392     LOG(ERROR) << "Failed to set uevent socket SO_RCVBUFFORCE option: " << strerror(errno);
393     return false;
394   }
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);
399     return false;
400   }
401   return true;
402 }
403
404 bool NetlinkManager::WatchSocket(unique_fd* netlink_fd) {
405   // Watch socket
406   bool watch_fd_rt = event_loop_->WatchFileDescriptor(
407       netlink_fd->get(),
408       EventLoop::kModeInput,
409       std::bind(&NetlinkManager::ReceivePacketAndRunHandler, this, _1));
410   if (!watch_fd_rt) {
411     LOG(ERROR) << "Failed to watch fd: " << netlink_fd->get();
412     return false;
413   }
414   return true;
415 }
416
417 uint16_t NetlinkManager::GetFamilyId() {
418   return message_types_[NL80211_GENL_NAME].family_id;
419 }
420
421 bool NetlinkManager::DiscoverFamilyId() {
422   NL80211Packet get_family_request(GENL_ID_CTRL,
423                                    CTRL_CMD_GETFAMILY,
424                                    GetSequenceNumber(),
425                                    getpid());
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";
431     return false;
432   }
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";
436     return false;
437   }
438   return true;
439 }
440
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";
445     return false;
446   }
447   uint32_t group_id = groups[group];
448   int err = setsockopt(async_netlink_fd_.get(),
449                        SOL_NETLINK,
450                        NETLINK_ADD_MEMBERSHIP,
451                        &group_id,
452                        sizeof(group_id));
453   if (err < 0) {
454     LOG(ERROR) << "Failed to setsockopt: " << strerror(errno);
455     return false;
456   }
457   return true;
458 }
459
460 void NetlinkManager::BroadcastHandler(unique_ptr<const NL80211Packet> packet) {
461   if (packet->GetMessageType() != GetFamilyId()) {
462     LOG(ERROR) << "Wrong family id for multicast message";
463     return;
464   }
465   uint32_t command = packet->GetCommand();
466
467   if (command == NL80211_CMD_NEW_SCAN_RESULTS ||
468       // Scan was aborted, for unspecified reasons.partial scan results may be
469       // available.
470       command == NL80211_CMD_SCAN_ABORTED) {
471     OnScanResultsReady(std::move(packet));
472     return;
473   }
474
475   if (command == NL80211_CMD_SCHED_SCAN_RESULTS) {
476     OnSchedScanResultsReady(std::move(packet));
477     return;
478   }
479
480
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));
492      return;
493   }
494 }
495
496 void NetlinkManager::OnMlmeEvent(unique_ptr<const NL80211Packet> packet) {
497   uint32_t if_index;
498
499   if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
500     LOG(ERROR) << "Failed to get interface index from a MLME event message";
501     return;
502   }
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;
507     return;
508   }
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));
514     }
515     return;
516   }
517   if (command == NL80211_CMD_ASSOCIATE) {
518     auto event = MlmeAssociateEvent::InitFromPacket(packet.get());
519     if (event != nullptr) {
520        handler->second->OnAssociate(std::move(event));
521     }
522     return;
523   }
524   if (command == NL80211_CMD_ROAM) {
525     auto event = MlmeRoamEvent::InitFromPacket(packet.get());
526     if (event != nullptr) {
527        handler->second->OnRoam(std::move(event));
528     }
529     return;
530   }
531 }
532
533 void NetlinkManager::OnSchedScanResultsReady(unique_ptr<const NL80211Packet> packet) {
534   uint32_t if_index;
535   if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
536     LOG(ERROR) << "Failed to get interface index from scan result notification";
537     return;
538   }
539
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;
544     return;
545   }
546   // Run scan result notification handler.
547   handler->second(if_index);
548 }
549
550 void NetlinkManager::OnScanResultsReady(unique_ptr<const NL80211Packet> packet) {
551   uint32_t if_index;
552   if (!packet->GetAttributeValue(NL80211_ATTR_IFINDEX, &if_index)) {
553     LOG(ERROR) << "Failed to get interface index from scan result notification";
554     return;
555   }
556   bool aborted = false;
557   if (packet->GetCommand() == NL80211_CMD_SCAN_ABORTED) {
558     aborted = true;
559   }
560
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;
565     return;
566   }
567
568   vector<vector<uint8_t>> ssids;
569   NL80211NestedAttr ssids_attr(0);
570   if (!packet->GetAttribute(NL80211_ATTR_SCAN_SSIDS, &ssids_attr)) {
571     if (!aborted) {
572       LOG(WARNING) << "Failed to get scan ssids from scan result notification";
573     }
574   } else {
575     if (!ssids_attr.GetListOfAttributeValues(&ssids)) {
576       return;
577     }
578   }
579   vector<uint32_t> freqs;
580   NL80211NestedAttr freqs_attr(0);
581   if (!packet->GetAttribute(NL80211_ATTR_SCAN_FREQUENCIES, &freqs_attr)) {
582     if (!aborted) {
583       LOG(WARNING) << "Failed to get scan freqs from scan result notification";
584     }
585   } else {
586     if (!freqs_attr.GetListOfAttributeValues(&freqs)) {
587       return;
588     }
589   }
590   // Run scan result notification handler.
591   handler->second(if_index, aborted, ssids, freqs);
592 }
593
594 void NetlinkManager::SubscribeScanResultNotification(
595     uint32_t interface_index,
596     OnScanResultsReadyHandler handler) {
597   on_scan_result_ready_handler_[interface_index] = handler;
598 }
599
600 void NetlinkManager::UnsubscribeScanResultNotification(
601     uint32_t interface_index) {
602   on_scan_result_ready_handler_.erase(interface_index);
603 }
604
605 void NetlinkManager::SubscribeMlmeEvent(uint32_t interface_index,
606                                         MlmeEventHandler* handler) {
607   on_mlme_event_handler_[interface_index] = handler;
608 }
609
610 void NetlinkManager::UnsubscribeMlmeEvent(uint32_t interface_index) {
611   on_mlme_event_handler_.erase(interface_index);
612 }
613
614 void NetlinkManager::SubscribeSchedScanResultNotification(
615       uint32_t interface_index,
616       OnSchedScanResultsReadyHandler handler) {
617   on_sched_scan_result_ready_handler_[interface_index] = handler;
618 }
619
620 void NetlinkManager::UnsubscribeSchedScanResultNotification(
621     uint32_t interface_index) {
622   on_sched_scan_result_ready_handler_.erase(interface_index);
623 }
624
625 }  // namespace wificond
626 }  // namespace android