diff options
author | Mike J. Chen <mjchen@google.com> | 2011-06-27 12:56:33 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-06-27 12:56:33 -0700 |
commit | 40cd7e0fdbbc7463b6fb367c0d9bf95dec82a13e (patch) | |
tree | 3f799bb26ae833753eed7769ce8a52bf7fec56de | |
parent | 26e0d49fa743d7881104196a9eda733bd2aac92f (diff) | |
parent | a583f8be6126d3116311e96c6fd8bafcbaf2b431 (diff) | |
download | netd-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.cpp | 27 | ||||
-rw-r--r-- | NetlinkHandler.h | 3 | ||||
-rw-r--r-- | NetlinkManager.cpp | 80 | ||||
-rw-r--r-- | NetlinkManager.h | 8 |
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 |