netd: NetlinkManager: add support receiving quota2 log messages

NetlinkManager, NetlinkHandler
 . added support for netlink's NETLINK_NFLOG family used by the updated xt_quota2.
 . it pushes the event all the wait to NetworkManagementService.java
    "linit alert <alert_name> <iface_name>"

This needs:
 - new kernel with quota2 changes that support logging via NETLINK's
   NETLINK_NFLOG family.
 - BandwidthController changes that setup the alerts.
 - system core NetlinkEvent that recognizes the NFLOG messages.
 - java land NetworkManagementService changes.

Change-Id: Id5b1026c6002803b5a1c0c7623cf7b1961de9802
diff --git a/NetlinkHandler.cpp b/NetlinkHandler.cpp
index 874e03f..8331ae0 100644
--- a/NetlinkHandler.cpp
+++ b/NetlinkHandler.cpp
@@ -68,7 +68,12 @@
         } else if (action == evt->NlActionLinkDown) {
             notifyInterfaceLinkChanged(iface, false);
         }
+    } else if (!strcmp(subsys, "qlog")) {
+        const char *alertName = evt->findParam("ALERT_NAME");
+        const char *iface = evt->findParam("INTERFACE");
+        notifyQuotaLimitReached(alertName, iface);
     }
+
 }
 
 void NetlinkHandler::notifyInterfaceAdded(const char *name) {
@@ -104,3 +109,11 @@
     mNm->getBroadcaster()->sendBroadcast(ResponseCode::InterfaceChange,
             msg, false);
 }
+
+void NetlinkHandler::notifyQuotaLimitReached(const char *name, const char *iface) {
+    char msg[255];
+    snprintf(msg, sizeof(msg), "limit alert %s %s", name, iface);
+
+    mNm->getBroadcaster()->sendBroadcast(ResponseCode::BandwidthControl,
+            msg, false);
+}
diff --git a/NetlinkHandler.h b/NetlinkHandler.h
index 492d6b1..9466ca6 100644
--- a/NetlinkHandler.h
+++ b/NetlinkHandler.h
@@ -37,5 +37,6 @@
     void notifyInterfaceRemoved(const char *name);
     void notifyInterfaceChanged(const char *name, bool isUp);
     void notifyInterfaceLinkChanged(const char *name, bool isUp);
+    void notifyQuotaLimitReached(const char *name, const char *iface);
 };
 #endif
diff --git a/NetlinkManager.cpp b/NetlinkManager.cpp
index 3e7a0a1..9af43b5 100644
--- a/NetlinkManager.cpp
+++ b/NetlinkManager.cpp
@@ -33,6 +33,8 @@
 #include "NetlinkManager.h"
 #include "NetlinkHandler.h"
 
+const int NetlinkManager::NFLOG_QUOTA_GROUP = 1;
+
 NetlinkManager *NetlinkManager::sInstance = NULL;
 
 NetlinkManager *NetlinkManager::Instance() {
@@ -48,7 +50,7 @@
 NetlinkManager::~NetlinkManager() {
 }
 
-NetlinkHandler *NetlinkManager::setupSocket(int *sock, int socketType,
+NetlinkHandler *NetlinkManager::setupSocket(int *sock, int netlinkFamily,
     int groups, int format) {
 
     struct sockaddr_nl nladdr;
@@ -60,7 +62,7 @@
     nladdr.nl_pid = getpid();
     nladdr.nl_groups = groups;
 
-    if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, socketType)) < 0) {
+    if ((*sock = socket(PF_NETLINK, SOCK_DGRAM, netlinkFamily)) < 0) {
         LOGE("Unable to create netlink socket: %s", strerror(errno));
         return NULL;
     }
@@ -103,6 +105,12 @@
          NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) {
         return -1;
     }
+
+    if ((mQuotaHandler = setupSocket(&mQuotaSock, NETLINK_NFLOG,
+        NFLOG_QUOTA_GROUP, NetlinkListener::NETLINK_FORMAT_BINARY)) == NULL) {
+        LOGE("Unable to open quota2 logging socket");
+        return -1;
+    }
     return 0;
 }
 
@@ -131,5 +139,16 @@
     close(mRouteSock);
     mRouteSock = -1;
 
+    if (mQuotaHandler->stop()) {
+        LOGE("Unable to stop quota NetlinkHandler: %s", strerror(errno));
+        status = -1;
+    }
+
+    delete mQuotaHandler;
+    mQuotaHandler = NULL;
+
+    close(mQuotaSock);
+    mQuotaSock = -1;
+
     return status;
 }
diff --git a/NetlinkManager.h b/NetlinkManager.h
index ff646f4..c8f5507 100644
--- a/NetlinkManager.h
+++ b/NetlinkManager.h
@@ -20,6 +20,7 @@
 #include <sysutils/SocketListener.h>
 #include <sysutils/NetlinkListener.h>
 
+
 class NetlinkHandler;
 
 class NetlinkManager {
@@ -30,8 +31,10 @@
     SocketListener       *mBroadcaster;
     NetlinkHandler       *mUeventHandler;
     NetlinkHandler       *mRouteHandler;
+    NetlinkHandler       *mQuotaHandler;
     int                  mUeventSock;
     int                  mRouteSock;
+    int                  mQuotaSock;
 
 public:
     virtual ~NetlinkManager();
@@ -44,9 +47,12 @@
 
     static NetlinkManager *Instance();
 
+    /* This is the nflog group arg that the xt_quota2 neftiler will use. */
+    static const int NFLOG_QUOTA_GROUP;
+
 private:
     NetlinkManager();
-    NetlinkHandler* setupSocket(int *sock, int socketType, int groups,
+    NetlinkHandler* setupSocket(int *sock, int netlinkFamily, int groups,
         int format);
 };
 #endif
diff --git a/ResponseCode.h b/ResponseCode.h
index be60eda..9d0ccb5 100644
--- a/ResponseCode.h
+++ b/ResponseCode.h
@@ -55,5 +55,6 @@
 
     // 600 series - Unsolicited broadcasts
     static const int InterfaceChange        = 600;
+    static const int BandwidthControl       = 601;
 };
 #endif