blob: fabf011459f4c62c37b3c20abfb6bbbb73145bec [file] [log] [blame]
San Mehatd1830422010-01-15 08:02:39 -08001/*
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>
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080027#include <linux/rtnetlink.h>
San Mehatd1830422010-01-15 08:02:39 -080028
29#define LOG_TAG "Netd"
30
31#include <cutils/log.h>
32
33#include "NetlinkManager.h"
34#include "NetlinkHandler.h"
35
36NetlinkManager *NetlinkManager::sInstance = NULL;
37
38NetlinkManager *NetlinkManager::Instance() {
39 if (!sInstance)
40 sInstance = new NetlinkManager();
41 return sInstance;
42}
43
44NetlinkManager::NetlinkManager() {
45 mBroadcaster = NULL;
46}
47
48NetlinkManager::~NetlinkManager() {
49}
50
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080051NetlinkHandler *NetlinkManager::setupSocket(int *sock, int socketType,
52 int groups, int format) {
53
San Mehatd1830422010-01-15 08:02:39 -080054 struct sockaddr_nl nladdr;
55 int sz = 64 * 1024;
56
57 memset(&nladdr, 0, sizeof(nladdr));
58 nladdr.nl_family = AF_NETLINK;
59 nladdr.nl_pid = getpid();
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080060 nladdr.nl_groups = groups;
San Mehatd1830422010-01-15 08:02:39 -080061
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080062 if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, socketType)) < 0) {
63 LOGE("Unable to create netlink socket: %s", strerror(errno));
64 return NULL;
San Mehatd1830422010-01-15 08:02:39 -080065 }
66
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080067 if (setsockopt(*sock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
68 LOGE("Unable to set netlink socket options: %s", strerror(errno));
69 close(*sock);
70 return NULL;
San Mehatd1830422010-01-15 08:02:39 -080071 }
72
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080073 if (bind(*sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
74 LOGE("Unable to bind netlink socket: %s", strerror(errno));
75 close(*sock);
76 return NULL;
San Mehatd1830422010-01-15 08:02:39 -080077 }
78
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080079 NetlinkHandler *handler = new NetlinkHandler(this, *sock, format);
80 if (handler->start()) {
San Mehatd1830422010-01-15 08:02:39 -080081 LOGE("Unable to start NetlinkHandler: %s", strerror(errno));
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -080082 close(*sock);
83 return NULL;
84 }
85
86 return handler;
87}
88
89int NetlinkManager::start() {
90 if ((mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT,
91 0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII)) == NULL) {
92 return -1;
93 }
94
95 if ((mRouteHandler = setupSocket(&mRouteSock, NETLINK_ROUTE, RTMGRP_LINK,
96 NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) {
San Mehatd1830422010-01-15 08:02:39 -080097 return -1;
98 }
99 return 0;
100}
101
102int NetlinkManager::stop() {
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -0800103 int status = 0;
104
105 if (mUeventHandler->stop()) {
106 LOGE("Unable to stop uevent NetlinkHandler: %s", strerror(errno));
107 status = -1;
San Mehatd1830422010-01-15 08:02:39 -0800108 }
San Mehatd1830422010-01-15 08:02:39 -0800109
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -0800110 delete mUeventHandler;
111 mUeventHandler = NULL;
San Mehatd1830422010-01-15 08:02:39 -0800112
Stan Chesnuttf6a7ad82011-01-05 11:47:37 -0800113 close(mUeventSock);
114 mUeventSock = -1;
115
116 if (mRouteHandler->stop()) {
117 LOGE("Unable to stop route NetlinkHandler: %s", strerror(errno));
118 status = -1;
119 }
120
121 delete mRouteHandler;
122 mRouteHandler = NULL;
123
124 close(mRouteSock);
125 mRouteSock = -1;
126
127 return status;
San Mehatd1830422010-01-15 08:02:39 -0800128}