1 /* 2 * Copyright (C) 2017 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 "netlink.h" 18 19 #include "log.h" 20 #include "netlinkmessage.h" 21 22 #include <errno.h> 23 #include <poll.h> 24 #include <string.h> 25 #include <linux/netlink.h> 26 #include <sys/socket.h> 27 #include <sys/types.h> 28 #include <unistd.h> 29 30 static const size_t kControlRead = 0; 31 static const size_t kControlWrite = 1; 32 33 static void closeIfOpen(int* fd) { 34 if (*fd != -1) { 35 ::close(*fd); 36 *fd = -1; 37 } 38 } 39 40 Netlink::Netlink() 41 : mNextSequenceNumber(1) 42 , mSocket(-1) { 43 mControlPipe[kControlRead] = -1; 44 mControlPipe[kControlWrite] = -1; 45 } 46 47 Netlink::~Netlink() { 48 closeIfOpen(&mSocket); 49 closeIfOpen(&mControlPipe[kControlRead]); 50 closeIfOpen(&mControlPipe[kControlWrite]); 51 } 52 53 bool Netlink::init() { 54 if (mSocket != -1) { 55 ALOGE("Netlink already initialized"); 56 return false; 57 } 58 59 int status = ::pipe2(mControlPipe, O_CLOEXEC); 60 if (status != 0) { 61 ALOGE("Failed to create control pipe: %s", strerror(errno)); 62 return false; 63 } 64 65 mSocket = ::socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE); 66 if (mSocket == -1) { 67 ALOGE("Failed to create netlink socket: %s", strerror(errno)); 68 return false; 69 } 70 71 struct sockaddr_nl addr; 72 memset(&addr, 0, sizeof(addr)); 73 addr.nl_family = AF_NETLINK; 74 status = ::bind(mSocket, 75 reinterpret_cast<struct sockaddr*>(&addr), 76 sizeof(addr)); 77 if (status != 0) { 78 ALOGE("Failed to bind netlink socket: %s", strerror(errno)); 79 return false; 80 } 81 82 return true; 83 } 84 85 void Netlink::stop(StopHandler handler) { 86 char stop = 1; 87 // Set the handler before writing so that it's guaranteed to be available 88 // when the event loop reads from the control pipe. 89 { 90 // No need to keep the lock while writing so make it scoped 91 std::unique_lock<std::mutex> lock(mStopHandlerMutex); 92 mStopHandler = handler; 93 } 94 ::write(mControlPipe[kControlWrite], &stop, sizeof(stop)); 95 } 96 97 bool Netlink::eventLoop() { 98 struct pollfd fds[2]; 99 memset(fds, 0, sizeof(fds)); 100 fds[0].fd = mSocket; 101 fds[0].events = POLLIN; 102 fds[1].fd = mControlPipe[kControlRead]; 103 fds[1].events = POLLIN; 104 105 for (;;) { 106 int status = ::poll(fds, 2, -1); 107 if (status == 0) { 108 // Timeout, not really supposed to happen 109 ALOGW("poll encountered a timeout despite infinite timeout"); 110 continue; 111 } else if (status < 0) { 112 if (errno == EINTR) { 113 continue; 114 } 115 ALOGE("poll encountered an error: %s", strerror(errno)); 116 return false; 117 } 118 for (auto& fd : fds) { 119 if ((fd.revents & POLLIN) == 0) { 120 continue; 121 } 122 if (fd.fd == mSocket) { 123 readNetlinkMessage(fd.fd); 124 } else if (fd.fd == mControlPipe[kControlRead]) { 125 if (readControlMessage()) { 126 // Make a copy of the stop handler while holding the lock 127 // and then call it after releasing the lock. This prevents 128 // the potential deadlock of someone calling stop from the 129 // stop callback. The drawback of this is that if someone 130 // calls stop again with a new stop handler that new stop 131 // handler might not be called if the timing is wrong. 132 // Both of these scenarios indicate highly questionable 133 // behavior on the callers part but at least this way the 134 // event loop will terminate which seems better than a 135 // total deadlock. 136 StopHandler handler; 137 { 138 std::unique_lock<std::mutex> lock(mStopHandlerMutex); 139 handler = mStopHandler; 140 } 141 if (handler) { 142 handler(); 143 } 144 return true; 145 } 146 } 147 } 148 } 149 } 150 151 uint32_t Netlink::getSequenceNumber() { 152 return mNextSequenceNumber++; 153 } 154 155 bool Netlink::sendMessage(const NetlinkMessage& message, 156 ReplyHandler handler) { 157 // Keep lock the entire time so that we can safely erase the handler 158 // without worrying about another call to sendAsync adding a handler that 159 // shouldn't be deleted. 160 std::unique_lock<std::mutex> lock(mHandlersMutex); 161 // Register handler before sending in case the read thread picks up the 162 // response between the send thread sending and registering the handler. 163 mHandlers[message.sequence()] = handler; 164 for (;;) { 165 int bytesSent = ::send(mSocket, message.data(), message.size(), 0); 166 if (bytesSent > 0 && static_cast<size_t>(bytesSent) == message.size()) { 167 return true; 168 } 169 if (bytesSent < 0 && errno == EINTR) { 170 // We need to try again, keep the mutex locked 171 continue; 172 } 173 // It's a failure, remove the handler and unlock the mutex 174 mHandlers.erase(message.sequence()); 175 lock.unlock(); 176 177 if (bytesSent < 0) { 178 ALOGE("Failed to send netlink message: %s", strerror(errno)); 179 } 180 return false; 181 } 182 } 183 184 bool Netlink::readNetlinkMessage(int fd) { 185 char buffer[8 * 1024]; 186 for (;;) { 187 int bytesReceived = ::recv(fd, buffer, sizeof(buffer), 0); 188 if (bytesReceived < 0) { 189 if (errno == EINTR) { 190 continue; 191 } 192 ALOGE("recv failed to receive on netlink socket: %s", 193 strerror(errno)); 194 return false; 195 } 196 char* data = buffer; 197 char* end = data + bytesReceived; 198 while (data < end) { 199 if (data + sizeof(nlmsghdr) > end) { 200 ALOGE("received invalid netlink message, too small for header"); 201 return false; 202 } 203 auto header = reinterpret_cast<nlmsghdr*>(data); 204 if (data + header->nlmsg_len > end) { 205 ALOGE("received invalid netlink message, too small for data"); 206 return false; 207 } 208 209 if (header->nlmsg_type == NLMSG_ERROR) { 210 if (data + NLMSG_HDRLEN + sizeof(nlmsgerr) <= end) { 211 auto err = reinterpret_cast<nlmsgerr*>(NLMSG_DATA(header)); 212 ALOGE("Receive netlink error message: %s, sequence %u", 213 strerror(-err->error), header->nlmsg_seq); 214 } else { 215 ALOGE("Received netlink error code but no error message"); 216 } 217 return false; 218 } 219 220 notifyHandler(data, header->nlmsg_len); 221 222 data += header->nlmsg_len; 223 } 224 return true; 225 } 226 } 227 228 bool Netlink::readControlMessage() { 229 char buffer[32]; 230 231 for (;;) { 232 int bytesReceived = ::recv(mControlPipe[kControlRead], 233 buffer, 234 sizeof(buffer), 235 0); 236 if (bytesReceived < 0) { 237 if (errno == EINTR) { 238 continue; 239 } 240 } else if (bytesReceived == 0) { 241 return false; 242 } 243 return true; 244 } 245 } 246 247 248 void Netlink::notifyHandler(const char* data, size_t size) { 249 NetlinkMessage message(data, size); 250 251 ReplyHandler replyHandler; 252 { 253 std::unique_lock<std::mutex> lock(mHandlersMutex); 254 auto handler = mHandlers.find(message.sequence()); 255 if (handler == mHandlers.end()) { 256 // No handler found, ignore message 257 return; 258 } 259 replyHandler = handler->second; 260 mHandlers.erase(handler); 261 } 262 263 replyHandler(message); 264 } 265 266