summaryrefslogtreecommitdiff
path: root/common/netd/libnetdutils/NetlinkListener.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/netd/libnetdutils/NetlinkListener.cpp')
-rw-r--r--common/netd/libnetdutils/NetlinkListener.cpp152
1 files changed, 0 insertions, 152 deletions
diff --git a/common/netd/libnetdutils/NetlinkListener.cpp b/common/netd/libnetdutils/NetlinkListener.cpp
deleted file mode 100644
index decaa9c8..00000000
--- a/common/netd/libnetdutils/NetlinkListener.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "NetlinkListener"
-
-#include <sstream>
-#include <vector>
-
-#include <linux/netfilter/nfnetlink.h>
-
-#include <log/log.h>
-#include <netdutils/Misc.h>
-#include <netdutils/NetlinkListener.h>
-#include <netdutils/Syscalls.h>
-
-namespace android {
-namespace netdutils {
-
-using netdutils::Fd;
-using netdutils::Slice;
-using netdutils::Status;
-using netdutils::UniqueFd;
-using netdutils::findWithDefault;
-using netdutils::forEachNetlinkMessage;
-using netdutils::makeSlice;
-using netdutils::sSyscalls;
-using netdutils::status::ok;
-using netdutils::statusFromErrno;
-
-namespace {
-
-constexpr int kNetlinkMsgErrorType = (NFNL_SUBSYS_NONE << 8) | NLMSG_ERROR;
-
-constexpr sockaddr_nl kKernelAddr = {
- .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = 0,
-};
-
-const NetlinkListener::DispatchFn kDefaultDispatchFn = [](const nlmsghdr& nlmsg, const Slice) {
- std::stringstream ss;
- ss << nlmsg;
- ALOGE("unhandled netlink message: %s", ss.str().c_str());
-};
-
-} // namespace
-
-NetlinkListener::NetlinkListener(UniqueFd event, UniqueFd sock, const std::string& name)
- : mEvent(std::move(event)), mSock(std::move(sock)), mThreadName(name) {
- const auto rxErrorHandler = [](const nlmsghdr& nlmsg, const Slice msg) {
- std::stringstream ss;
- ss << nlmsg << " " << msg << " " << netdutils::toHex(msg, 32);
- ALOGE("unhandled netlink message: %s", ss.str().c_str());
- };
- expectOk(NetlinkListener::subscribe(kNetlinkMsgErrorType, rxErrorHandler));
-
- mErrorHandler = [& name = mThreadName](const int fd, const int err) {
- ALOGE("Error on NetlinkListener(%s) fd=%d: %s", name.c_str(), fd, strerror(err));
- };
-
- // Start the thread
- mWorker = std::thread([this]() { run().ignoreError(); });
-}
-
-NetlinkListener::~NetlinkListener() {
- const auto& sys = sSyscalls.get();
- const uint64_t data = 1;
- // eventfd should never enter an error state unexpectedly
- expectOk(sys.write(mEvent, makeSlice(data)).status());
- mWorker.join();
-}
-
-Status NetlinkListener::send(const Slice msg) {
- const auto& sys = sSyscalls.get();
- ASSIGN_OR_RETURN(auto sent, sys.sendto(mSock, msg, 0, kKernelAddr));
- if (sent != msg.size()) {
- return statusFromErrno(EMSGSIZE, "unexpect message size");
- }
- return ok;
-}
-
-Status NetlinkListener::subscribe(uint16_t type, const DispatchFn& fn) {
- std::lock_guard guard(mMutex);
- mDispatchMap[type] = fn;
- return ok;
-}
-
-Status NetlinkListener::unsubscribe(uint16_t type) {
- std::lock_guard guard(mMutex);
- mDispatchMap.erase(type);
- return ok;
-}
-
-void NetlinkListener::registerSkErrorHandler(const SkErrorHandler& handler) {
- mErrorHandler = handler;
-}
-
-Status NetlinkListener::run() {
- std::vector<char> rxbuf(4096);
-
- const auto rxHandler = [this](const nlmsghdr& nlmsg, const Slice& buf) {
- std::lock_guard guard(mMutex);
- const auto& fn = findWithDefault(mDispatchMap, nlmsg.nlmsg_type, kDefaultDispatchFn);
- fn(nlmsg, buf);
- };
-
- if (mThreadName.length() > 0) {
- int ret = pthread_setname_np(pthread_self(), mThreadName.c_str());
- if (ret) {
- ALOGE("thread name set failed, name: %s, ret: %s", mThreadName.c_str(), strerror(ret));
- }
- }
- const auto& sys = sSyscalls.get();
- const std::array<Fd, 2> fds{{{mEvent}, {mSock}}};
- const int events = POLLIN;
- const double timeout = 3600;
- while (true) {
- ASSIGN_OR_RETURN(auto revents, sys.ppoll(fds, events, timeout));
- // After mEvent becomes readable, we should stop servicing mSock and return
- if (revents[0] & POLLIN) {
- break;
- }
- if (revents[1] & (POLLIN|POLLERR)) {
- auto rx = sys.recvfrom(mSock, makeSlice(rxbuf), 0);
- int err = rx.status().code();
- if (err) {
- // Ignore errors. The only error we expect to see here is ENOBUFS, and there's
- // nothing we can do about that. The recvfrom above will already have cleared the
- // error indication and ensured we won't get EPOLLERR again.
- // TODO: Consider using NETLINK_NO_ENOBUFS.
- mErrorHandler(((Fd) mSock).get(), err);
- continue;
- }
- forEachNetlinkMessage(rx.value(), rxHandler);
- }
- }
- return ok;
-}
-
-} // namespace netdutils
-} // namespace android