1 /* 2 * Copyright (C) 2008 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 <stdio.h> 18 #include <errno.h> 19 20 #include <sys/socket.h> 21 #include <sys/select.h> 22 #include <sys/time.h> 23 #include <sys/types.h> 24 #include <sys/un.h> 25 26 #include <linux/netlink.h> 27 #include <linux/rtnetlink.h> 28 29 #define LOG_TAG "Netd" 30 31 #include <cutils/log.h> 32 33 #include "NetlinkManager.h" 34 #include "NetlinkHandler.h" 35 36 const int NetlinkManager::NFLOG_QUOTA_GROUP = 1; 37 38 NetlinkManager *NetlinkManager::sInstance = NULL; 39 40 NetlinkManager *NetlinkManager::Instance() { 41 if (!sInstance) 42 sInstance = new NetlinkManager(); 43 return sInstance; 44 } 45 46 NetlinkManager::NetlinkManager() { 47 mBroadcaster = NULL; 48 } 49 50 NetlinkManager::~NetlinkManager() { 51 } 52 53 NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily, 54 int groups, int format) { 55 56 struct sockaddr_nl nladdr; 57 int sz = 64 * 1024; 58 int on = 1; 59 60 memset(&nladdr, 0, sizeof(nladdr)); 61 nladdr.nl_family = AF_NETLINK; 62 nladdr.nl_pid = getpid(); 63 nladdr.nl_groups = groups; 64 65 if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, netlinkFamily)) < 0) { 66 LOGE("Unable to create netlink socket: %s", strerror(errno)); 67 return NULL; 68 } 69 70 if (setsockopt(*sock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) { 71 LOGE("Unable to set uevent socket SO_RCVBUFFORCE option: %s", strerror(errno)); 72 close(*sock); 73 return NULL; 74 } 75 76 if (setsockopt(*sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) { 77 SLOGE("Unable to set uevent socket SO_PASSCRED option: %s", strerror(errno)); 78 close(*sock); 79 return NULL; 80 } 81 82 if (bind(*sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) { 83 LOGE("Unable to bind netlink socket: %s", strerror(errno)); 84 close(*sock); 85 return NULL; 86 } 87 88 NetlinkHandler *handler = new NetlinkHandler(this, *sock, format); 89 if (handler->start()) { 90 LOGE("Unable to start NetlinkHandler: %s", strerror(errno)); 91 close(*sock); 92 return NULL; 93 } 94 95 return handler; 96 } 97 98 int NetlinkManager::start() { 99 if ((mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT, 100 0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII)) == NULL) { 101 return -1; 102 } 103 104 if ((mRouteHandler = setupSocket(&mRouteSock, NETLINK_ROUTE, RTMGRP_LINK, 105 NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) { 106 return -1; 107 } 108 109 if ((mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG, 110 NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) { 111 LOGE("Unable to open quota2 logging socket"); 112 // TODO: return -1 once the emulator gets a new kernel. 113 } 114 return 0; 115 } 116 117 int NetlinkManager::stop() { 118 int status = 0; 119 120 if (mUeventHandler->stop()) { 121 LOGE("Unable to stop uevent NetlinkHandler: %s", strerror(errno)); 122 status = -1; 123 } 124 125 delete mUeventHandler; 126 mUeventHandler = NULL; 127 128 close(mUeventSock); 129 mUeventSock = -1; 130 131 if (mRouteHandler->stop()) { 132 LOGE("Unable to stop route NetlinkHandler: %s", strerror(errno)); 133 status = -1; 134 } 135 136 delete mRouteHandler; 137 mRouteHandler = NULL; 138 139 close(mRouteSock); 140 mRouteSock = -1; 141 142 if (mQuotaHandler) { 143 if (mQuotaHandler->stop()) { 144 LOGE("Unable to stop quota NetlinkHandler: %s", strerror(errno)); 145 status = -1; 146 } 147 148 delete mQuotaHandler; 149 mQuotaHandler = NULL; 150 151 close(mQuotaSock); 152 mQuotaSock = -1; 153 } 154 return status; 155 } 156