xref: /aosp_15_r20/system/vold/NetlinkManager.cpp (revision f40fafd4c6c2594924d919feffc1a1fd6e3b30f3)
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