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
closeIfOpen(int * fd)33 static void closeIfOpen(int* fd) {
34 if (*fd != -1) {
35 ::close(*fd);
36 *fd = -1;
37 }
38 }
39
Netlink()40 Netlink::Netlink()
41 : mNextSequenceNumber(1)
42 , mSocket(-1) {
43 mControlPipe[kControlRead] = -1;
44 mControlPipe[kControlWrite] = -1;
45 }
46
~Netlink()47 Netlink::~Netlink() {
48 closeIfOpen(&mSocket);
49 closeIfOpen(&mControlPipe[kControlRead]);
50 closeIfOpen(&mControlPipe[kControlWrite]);
51 }
52
init()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
stop(StopHandler handler)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
eventLoop()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
getSequenceNumber()151 uint32_t Netlink::getSequenceNumber() {
152 return mNextSequenceNumber++;
153 }
154
sendMessage(const NetlinkMessage & message,ReplyHandler handler)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
readNetlinkMessage(int fd)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
readControlMessage()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
notifyHandler(const char * data,size_t size)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