summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike J. Chen <mjchen@google.com>2011-06-27 12:56:33 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-06-27 12:56:33 -0700
commit40cd7e0fdbbc7463b6fb367c0d9bf95dec82a13e (patch)
tree3f799bb26ae833753eed7769ce8a52bf7fec56de
parent26e0d49fa743d7881104196a9eda733bd2aac92f (diff)
parenta583f8be6126d3116311e96c6fd8bafcbaf2b431 (diff)
downloadnetd-40cd7e0fdbbc7463b6fb367c0d9bf95dec82a13e.tar.gz
Merge changes Ie9674ca0,I8c0625a9
* changes: Change string notification for link state change. Revert "Revert "Add NETLINK_ROUTE socket creation and event propagation""
-rw-r--r--NetlinkHandler.cpp27
-rw-r--r--NetlinkHandler.h3
-rw-r--r--NetlinkManager.cpp80
-rw-r--r--NetlinkManager.h8
4 files changed, 86 insertions, 32 deletions
diff --git a/NetlinkHandler.cpp b/NetlinkHandler.cpp
index 800c86cb..874e03fb 100644
--- a/NetlinkHandler.cpp
+++ b/NetlinkHandler.cpp
@@ -28,8 +28,9 @@
#include "NetlinkManager.h"
#include "ResponseCode.h"
-NetlinkHandler::NetlinkHandler(NetlinkManager *nm, int listenerSocket) :
- NetlinkListener(listenerSocket) {
+NetlinkHandler::NetlinkHandler(NetlinkManager *nm, int listenerSocket,
+ int format) :
+ NetlinkListener(listenerSocket, format) {
mNm = nm;
}
@@ -50,18 +51,22 @@ void NetlinkHandler::onEvent(NetlinkEvent *evt) {
LOGW("No subsystem found in netlink event");
return;
}
+
if (!strcmp(subsys, "net")) {
int action = evt->getAction();
+ const char *iface = evt->findParam("INTERFACE");
+
if (action == evt->NlActionAdd) {
- const char *iface = evt->findParam("INTERFACE");
notifyInterfaceAdded(iface);
} else if (action == evt->NlActionRemove) {
- const char *iface = evt->findParam("INTERFACE");
notifyInterfaceRemoved(iface);
} else if (action == evt->NlActionChange) {
evt->dump();
- const char *iface = evt->findParam("INTERFACE");
notifyInterfaceChanged("nana", true);
+ } else if (action == evt->NlActionLinkUp) {
+ notifyInterfaceLinkChanged(iface, true);
+ } else if (action == evt->NlActionLinkDown) {
+ notifyInterfaceLinkChanged(iface, false);
}
}
}
@@ -84,7 +89,17 @@ void NetlinkHandler::notifyInterfaceRemoved(const char *name) {
void NetlinkHandler::notifyInterfaceChanged(const char *name, bool isUp) {
char msg[255];
- snprintf(msg, sizeof(msg), "Iface is %s %s", (isUp ? "up" : "down"), name);
+ snprintf(msg, sizeof(msg), "Iface changed %s %s", name,
+ (isUp ? "up" : "down"));
+
+ mNm->getBroadcaster()->sendBroadcast(ResponseCode::InterfaceChange,
+ msg, false);
+}
+
+void NetlinkHandler::notifyInterfaceLinkChanged(const char *name, bool isUp) {
+ char msg[255];
+ snprintf(msg, sizeof(msg), "Iface linkstate %s %s", name,
+ (isUp ? "up" : "down"));
mNm->getBroadcaster()->sendBroadcast(ResponseCode::InterfaceChange,
msg, false);
diff --git a/NetlinkHandler.h b/NetlinkHandler.h
index 8b2498f7..492d6b19 100644
--- a/NetlinkHandler.h
+++ b/NetlinkHandler.h
@@ -24,7 +24,7 @@ class NetlinkHandler: public NetlinkListener {
NetlinkManager *mNm;
public:
- NetlinkHandler(NetlinkManager *nm, int listenerSocket);
+ NetlinkHandler(NetlinkManager *nm, int listenerSocket, int format);
virtual ~NetlinkHandler();
int start(void);
@@ -36,5 +36,6 @@ protected:
void notifyInterfaceAdded(const char *name);
void notifyInterfaceRemoved(const char *name);
void notifyInterfaceChanged(const char *name, bool isUp);
+ void notifyInterfaceLinkChanged(const char *name, bool isUp);
};
#endif
diff --git a/NetlinkManager.cpp b/NetlinkManager.cpp
index e7f0c7b8..3e7a0a12 100644
--- a/NetlinkManager.cpp
+++ b/NetlinkManager.cpp
@@ -24,6 +24,7 @@
#include <sys/un.h>
#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
#define LOG_TAG "Netd"
@@ -47,7 +48,9 @@ NetlinkManager::NetlinkManager() {
NetlinkManager::~NetlinkManager() {
}
-int NetlinkManager::start() {
+NetlinkHandler *NetlinkManager::setupSocket(int *sock, int socketType,
+ int groups, int format) {
+
struct sockaddr_nl nladdr;
int sz = 64 * 1024;
int on = 1;
@@ -55,47 +58,78 @@ int NetlinkManager::start() {
memset(&nladdr, 0, sizeof(nladdr));
nladdr.nl_family = AF_NETLINK;
nladdr.nl_pid = getpid();
- nladdr.nl_groups = 0xffffffff;
+ nladdr.nl_groups = groups;
- if ((mSock = socket(PF_NETLINK,
- SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {
- LOGE("Unable to create uevent socket: %s", strerror(errno));
- return -1;
+ if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, socketType)) < 0) {
+ LOGE("Unable to create netlink socket: %s", strerror(errno));
+ return NULL;
}
- if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
+ if (setsockopt(*sock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {
LOGE("Unable to set uevent socket SO_RCVBUFFORCE option: %s", strerror(errno));
- return -1;
+ close(*sock);
+ return NULL;
}
- if (setsockopt(mSock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
+ if (setsockopt(*sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)) < 0) {
SLOGE("Unable to set uevent socket SO_PASSCRED option: %s", strerror(errno));
- return -1;
+ close(*sock);
+ return NULL;
}
- if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
- LOGE("Unable to bind uevent socket: %s", strerror(errno));
- return -1;
+ if (bind(*sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {
+ LOGE("Unable to bind netlink socket: %s", strerror(errno));
+ close(*sock);
+ return NULL;
}
- mHandler = new NetlinkHandler(this, mSock);
- if (mHandler->start()) {
+ NetlinkHandler *handler = new NetlinkHandler(this, *sock, format);
+ if (handler->start()) {
LOGE("Unable to start NetlinkHandler: %s", strerror(errno));
+ close(*sock);
+ return NULL;
+ }
+
+ return handler;
+}
+
+int NetlinkManager::start() {
+ if ((mUeventHandler = setupSocket(&mUeventSock, NETLINK_KOBJECT_UEVENT,
+ 0xffffffff, NetlinkListener::NETLINK_FORMAT_ASCII)) == NULL) {
+ return -1;
+ }
+
+ if ((mRouteHandler = setupSocket(&mRouteSock, NETLINK_ROUTE, RTMGRP_LINK,
+ NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) {
return -1;
}
return 0;
}
int NetlinkManager::stop() {
- if (mHandler->stop()) {
- LOGE("Unable to stop NetlinkHandler: %s", strerror(errno));
- return -1;
+ int status = 0;
+
+ if (mUeventHandler->stop()) {
+ LOGE("Unable to stop uevent NetlinkHandler: %s", strerror(errno));
+ status = -1;
}
- delete mHandler;
- mHandler = NULL;
- close(mSock);
- mSock = -1;
+ delete mUeventHandler;
+ mUeventHandler = NULL;
- return 0;
+ close(mUeventSock);
+ mUeventSock = -1;
+
+ if (mRouteHandler->stop()) {
+ LOGE("Unable to stop route NetlinkHandler: %s", strerror(errno));
+ status = -1;
+ }
+
+ delete mRouteHandler;
+ mRouteHandler = NULL;
+
+ close(mRouteSock);
+ mRouteSock = -1;
+
+ return status;
}
diff --git a/NetlinkManager.h b/NetlinkManager.h
index 9c7ba11c..ff646f48 100644
--- a/NetlinkManager.h
+++ b/NetlinkManager.h
@@ -28,8 +28,10 @@ private:
private:
SocketListener *mBroadcaster;
- NetlinkHandler *mHandler;
- int mSock;
+ NetlinkHandler *mUeventHandler;
+ NetlinkHandler *mRouteHandler;
+ int mUeventSock;
+ int mRouteSock;
public:
virtual ~NetlinkManager();
@@ -44,5 +46,7 @@ public:
private:
NetlinkManager();
+ NetlinkHandler* setupSocket(int *sock, int socketType, int groups,
+ int format);
};
#endif