1*f40fafd4SAndroid Build Coastguard Worker /*
2*f40fafd4SAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project
3*f40fafd4SAndroid Build Coastguard Worker *
4*f40fafd4SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*f40fafd4SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*f40fafd4SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*f40fafd4SAndroid Build Coastguard Worker *
8*f40fafd4SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*f40fafd4SAndroid Build Coastguard Worker *
10*f40fafd4SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*f40fafd4SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*f40fafd4SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*f40fafd4SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*f40fafd4SAndroid Build Coastguard Worker * limitations under the License.
15*f40fafd4SAndroid Build Coastguard Worker */
16*f40fafd4SAndroid Build Coastguard Worker
17*f40fafd4SAndroid Build Coastguard Worker #include <errno.h>
18*f40fafd4SAndroid Build Coastguard Worker #include <stdio.h>
19*f40fafd4SAndroid Build Coastguard Worker #include <string.h>
20*f40fafd4SAndroid Build Coastguard Worker
21*f40fafd4SAndroid Build Coastguard Worker #include <sys/select.h>
22*f40fafd4SAndroid Build Coastguard Worker #include <sys/socket.h>
23*f40fafd4SAndroid Build Coastguard Worker #include <sys/time.h>
24*f40fafd4SAndroid Build Coastguard Worker #include <sys/types.h>
25*f40fafd4SAndroid Build Coastguard Worker #include <sys/un.h>
26*f40fafd4SAndroid Build Coastguard Worker
27*f40fafd4SAndroid Build Coastguard Worker #include <linux/netlink.h>
28*f40fafd4SAndroid Build Coastguard Worker
29*f40fafd4SAndroid Build Coastguard Worker #include <android-base/logging.h>
30*f40fafd4SAndroid Build Coastguard Worker
31*f40fafd4SAndroid Build Coastguard Worker #include "NetlinkHandler.h"
32*f40fafd4SAndroid Build Coastguard Worker #include "NetlinkManager.h"
33*f40fafd4SAndroid Build Coastguard Worker
34*f40fafd4SAndroid Build Coastguard Worker NetlinkManager* NetlinkManager::sInstance = NULL;
35*f40fafd4SAndroid Build Coastguard Worker
Instance()36*f40fafd4SAndroid Build Coastguard Worker NetlinkManager* NetlinkManager::Instance() {
37*f40fafd4SAndroid Build Coastguard Worker if (!sInstance) sInstance = new NetlinkManager();
38*f40fafd4SAndroid Build Coastguard Worker return sInstance;
39*f40fafd4SAndroid Build Coastguard Worker }
40*f40fafd4SAndroid Build Coastguard Worker
NetlinkManager()41*f40fafd4SAndroid Build Coastguard Worker NetlinkManager::NetlinkManager() {
42*f40fafd4SAndroid Build Coastguard Worker mBroadcaster = NULL;
43*f40fafd4SAndroid Build Coastguard Worker }
44*f40fafd4SAndroid Build Coastguard Worker
~NetlinkManager()45*f40fafd4SAndroid Build Coastguard Worker NetlinkManager::~NetlinkManager() {}
46*f40fafd4SAndroid Build Coastguard Worker
start()47*f40fafd4SAndroid Build Coastguard Worker int NetlinkManager::start() {
48*f40fafd4SAndroid Build Coastguard Worker struct sockaddr_nl nladdr;
49*f40fafd4SAndroid Build Coastguard Worker int sz = 256 * 1024;
50*f40fafd4SAndroid Build Coastguard Worker int on = 1;
51*f40fafd4SAndroid Build Coastguard Worker
52*f40fafd4SAndroid Build Coastguard Worker memset(&nladdr, 0, sizeof(nladdr));
53*f40fafd4SAndroid Build Coastguard Worker nladdr.nl_family = AF_NETLINK;
54*f40fafd4SAndroid Build Coastguard Worker nladdr.nl_pid = getpid();
55*f40fafd4SAndroid Build Coastguard Worker nladdr.nl_groups = 0xffffffff;
56*f40fafd4SAndroid Build Coastguard Worker
57*f40fafd4SAndroid Build Coastguard Worker if ((mSock = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_KOBJECT_UEVENT)) < 0) {
58*f40fafd4SAndroid Build Coastguard Worker PLOG(ERROR) << "Unable to create uevent socket";
59*f40fafd4SAndroid Build Coastguard Worker return -1;
60*f40fafd4SAndroid Build Coastguard Worker }
61*f40fafd4SAndroid Build Coastguard Worker
62*f40fafd4SAndroid Build Coastguard Worker // When running in a net/user namespace, SO_RCVBUFFORCE will fail because
63*f40fafd4SAndroid Build Coastguard Worker // it will check for the CAP_NET_ADMIN capability in the root namespace.
64*f40fafd4SAndroid Build Coastguard Worker // Try using SO_RCVBUF if that fails.
65*f40fafd4SAndroid Build Coastguard Worker if ((setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) &&
66*f40fafd4SAndroid Build Coastguard Worker (setsockopt(mSock, SOL_SOCKET, SO_RCVBUF, &sz, sizeof(sz)) < 0)) {
67*f40fafd4SAndroid Build Coastguard Worker PLOG(ERROR) << "Unable to set uevent socket SO_RCVBUF/SO_RCVBUFFORCE option";
68*f40fafd4SAndroid Build Coastguard Worker goto out;
69*f40fafd4SAndroid Build Coastguard Worker }
70*f40fafd4SAndroid Build Coastguard Worker
71*f40fafd4SAndroid Build Coastguard Worker if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
72*f40fafd4SAndroid Build Coastguard Worker PLOG(ERROR) << "Unable to set uevent socket SO_PASSCRED option";
73*f40fafd4SAndroid Build Coastguard Worker goto out;
74*f40fafd4SAndroid Build Coastguard Worker }
75*f40fafd4SAndroid Build Coastguard Worker
76*f40fafd4SAndroid Build Coastguard Worker if (bind(mSock, (struct sockaddr*)&nladdr, sizeof(nladdr)) < 0) {
77*f40fafd4SAndroid Build Coastguard Worker PLOG(ERROR) << "Unable to bind uevent socket";
78*f40fafd4SAndroid Build Coastguard Worker goto out;
79*f40fafd4SAndroid Build Coastguard Worker }
80*f40fafd4SAndroid Build Coastguard Worker
81*f40fafd4SAndroid Build Coastguard Worker mHandler = new NetlinkHandler(mSock);
82*f40fafd4SAndroid Build Coastguard Worker if (mHandler->start()) {
83*f40fafd4SAndroid Build Coastguard Worker PLOG(ERROR) << "Unable to start NetlinkHandler";
84*f40fafd4SAndroid Build Coastguard Worker goto out;
85*f40fafd4SAndroid Build Coastguard Worker }
86*f40fafd4SAndroid Build Coastguard Worker
87*f40fafd4SAndroid Build Coastguard Worker return 0;
88*f40fafd4SAndroid Build Coastguard Worker
89*f40fafd4SAndroid Build Coastguard Worker out:
90*f40fafd4SAndroid Build Coastguard Worker close(mSock);
91*f40fafd4SAndroid Build Coastguard Worker return -1;
92*f40fafd4SAndroid Build Coastguard Worker }
93