OSDN Git Service

Setup interfaces for IPv6 tethering
authorErik Kline <ek@google.com>
Wed, 8 Jun 2016 04:24:45 +0000 (13:24 +0900)
committerErik Kline <ek@google.com>
Wed, 29 Jun 2016 09:41:07 +0000 (18:41 +0900)
Including:
    - set the interface for router mode (accept_ra = 0)
    - reset the interface for client mode (accept_ra = 1)
    - InterfaceController::setAcceptIPv6Ra()
    - InterfaceController::setAcceptIPv6Dad()
    - make InterfaceController static
    - refactor for more modern C++ usage here and there
    - sporadic style guide fixes

Bug: 9580643
Change-Id: Ia557c8770e18c58b12ad16d982c63b6ebd525516

server/CommandListener.cpp
server/Controllers.cpp
server/Controllers.h
server/InterfaceController.cpp
server/InterfaceController.h
server/TetherController.cpp
server/TetherController.h

index 4c4681d..6d0e088 100644 (file)
@@ -42,6 +42,7 @@
 #include "ResponseCode.h"
 #include "BandwidthController.h"
 #include "IdletimerController.h"
+#include "InterfaceController.h"
 #include "oem_iptables_hook.h"
 #include "NetdConstants.h"
 #include "FirewallController.h"
@@ -414,7 +415,7 @@ int CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
                 return 0;
             }
             int enable = !strncmp(argv[3], "enable", 7);
-            if (gCtls->interfaceCtrl.setIPv6PrivacyExtensions(argv[2], enable) == 0) {
+            if (InterfaceController::setIPv6PrivacyExtensions(argv[2], enable) == 0) {
                 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 privacy extensions changed", false);
             } else {
                 cli->sendMsg(ResponseCode::OperationFailed,
@@ -430,7 +431,7 @@ int CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
             }
 
             int enable = !strncmp(argv[3], "enable", 7);
-            if (gCtls->interfaceCtrl.setEnableIPv6(argv[2], enable) == 0) {
+            if (InterfaceController::setEnableIPv6(argv[2], enable) == 0) {
                 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 state changed", false);
             } else {
                 cli->sendMsg(ResponseCode::OperationFailed,
@@ -445,7 +446,7 @@ int CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
                 return 0;
             }
             int enable = !strncmp(argv[3], "enable", 7);
-            if (gCtls->interfaceCtrl.setIPv6NdOffload(argv[2], enable) == 0) {
+            if (InterfaceController::setIPv6NdOffload(argv[2], enable) == 0) {
                 cli->sendMsg(ResponseCode::CommandOkay, "IPv6 ND offload changed", false);
             } else {
                 cli->sendMsg(ResponseCode::OperationFailed,
@@ -458,7 +459,7 @@ int CommandListener::InterfaceCmd::runCommand(SocketClient *cli,
                         "Usage: interface setmtu <interface> <val>", false);
                 return 0;
             }
-            if (gCtls->interfaceCtrl.setMtu(argv[2], argv[3]) == 0) {
+            if (InterfaceController::setMtu(argv[2], argv[3]) == 0) {
                 cli->sendMsg(ResponseCode::CommandOkay, "MTU changed", false);
             } else {
                 cli->sendMsg(ResponseCode::OperationFailed,
@@ -576,17 +577,15 @@ int CommandListener::TetherCmd::runCommand(SocketClient *cli,
         return 0;
     } else if (argc == 3) {
         if (!strcmp(argv[1], "interface") && !strcmp(argv[2], "list")) {
-            InterfaceCollection *ilist = gCtls->tetherCtrl.getTetheredInterfaceList();
-            InterfaceCollection::iterator it;
-            for (it = ilist->begin(); it != ilist->end(); ++it) {
-                cli->sendMsg(ResponseCode::TetherInterfaceListResult, *it, false);
+            for (const auto &ifname : gCtls->tetherCtrl.getTetheredInterfaceList()) {
+                cli->sendMsg(ResponseCode::TetherInterfaceListResult, ifname.c_str(), false);
             }
         } else if (!strcmp(argv[1], "dns") && !strcmp(argv[2], "list")) {
             char netIdStr[UINT32_STRLEN];
             snprintf(netIdStr, sizeof(netIdStr), "%u", gCtls->tetherCtrl.getDnsNetId());
             cli->sendMsg(ResponseCode::TetherDnsFwdNetIdResult, netIdStr, false);
 
-            for (const auto &fwdr : *(gCtls->tetherCtrl.getDnsForwarders())) {
+            for (const auto &fwdr : gCtls->tetherCtrl.getDnsForwarders()) {
                 cli->sendMsg(ResponseCode::TetherDnsFwdTgtListResult, fwdr.c_str(), false);
             }
         }
index 07e5653..85c7c96 100644 (file)
@@ -19,7 +19,9 @@
 namespace android {
 namespace net {
 
-Controllers::Controllers() : clatdCtrl(&netCtrl) {}
+Controllers::Controllers() : clatdCtrl(&netCtrl) {
+    InterfaceController::initializeAll();
+}
 
 Controllers* gCtls = nullptr;
 
index 5634800..142a244 100644 (file)
@@ -47,7 +47,6 @@ struct Controllers {
     IdletimerController idletimerCtrl;
     ResolverController resolverCtrl;
     FirewallController firewallCtrl;
-    InterfaceController interfaceCtrl;
     ClatdController clatdCtrl;
     StrictController strictCtrl;
 };
index a9cf48f..cbc3611 100644 (file)
@@ -82,28 +82,25 @@ void setIPv6UseOutgoingInterfaceAddrsOnly(const char *value) {
 
 }  // namespace
 
-InterfaceController::InterfaceController() {
-       // Initial IPv6 settings.
-       // By default, accept_ra is set to 1 (accept RAs unless forwarding is on) on all interfaces.
-       // This causes RAs to work or not work based on whether forwarding is on, and causes routes
-       // learned from RAs to go away when forwarding is turned on. Make this behaviour predictable
-       // by always setting accept_ra to 2.
-       setAcceptRA("2");
+void InterfaceController::initializeAll() {
+    // Initial IPv6 settings.
+    // By default, accept_ra is set to 1 (accept RAs unless forwarding is on) on all interfaces.
+    // This causes RAs to work or not work based on whether forwarding is on, and causes routes
+    // learned from RAs to go away when forwarding is turned on. Make this behaviour predictable
+    // by always setting accept_ra to 2.
+    setAcceptRA("2");
 
-       setAcceptRARouteTable(-RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX);
+    setAcceptRARouteTable(-RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX);
 
-       // Enable optimistic DAD for IPv6 addresses on all interfaces.
-       setIPv6OptimisticMode("1");
+    // Enable optimistic DAD for IPv6 addresses on all interfaces.
+    setIPv6OptimisticMode("1");
 
-       // Reduce the ARP/ND base reachable time from the default (30sec) to 15sec.
-       setBaseReachableTimeMs(15 * 1000);
+    // Reduce the ARP/ND base reachable time from the default (30sec) to 15sec.
+    setBaseReachableTimeMs(15 * 1000);
 
-       // When sending traffic via a given interface use only addresses configured
-        // on that interface as possible source addresses.
-       setIPv6UseOutgoingInterfaceAddrsOnly("1");
-}
-
-InterfaceController::~InterfaceController() {
+    // When sending traffic via a given interface use only addresses configured
+       // on that interface as possible source addresses.
+    setIPv6UseOutgoingInterfaceAddrsOnly("1");
 }
 
 int InterfaceController::setEnableIPv6(const char *interface, const int on) {
@@ -118,6 +115,26 @@ int InterfaceController::setEnableIPv6(const char *interface, const int on) {
     return writeValueToPath(ipv6_proc_path, interface, "disable_ipv6", disable_ipv6);
 }
 
+int InterfaceController::setAcceptIPv6Ra(const char *interface, const int on) {
+    if (!isIfaceName(interface)) {
+        errno = ENOENT;
+        return -1;
+    }
+    // Because forwarding can be enabled even when tethering is off, we always
+    // use mode "2" (accept RAs, even if forwarding is enabled).
+    const char *accept_ra = on ? "2" : "0";
+    return writeValueToPath(ipv6_proc_path, interface, "accept_ra", accept_ra);
+}
+
+int InterfaceController::setAcceptIPv6Dad(const char *interface, const int on) {
+    if (!isIfaceName(interface)) {
+        errno = ENOENT;
+        return -1;
+    }
+    const char *accept_dad = on ? "1" : "0";
+    return writeValueToPath(ipv6_proc_path, interface, "accept_dad", accept_dad);
+}
+
 int InterfaceController::setIPv6PrivacyExtensions(const char *interface, const int on) {
     if (!isIfaceName(interface)) {
         errno = ENOENT;
index 89728b1..4c8057e 100644 (file)
 #define _INTERFACE_CONTROLLER_H
 
 class InterfaceController {
- public:
-       InterfaceController();
-       virtual ~InterfaceController();
-       int setEnableIPv6(const char *interface, const int on);
-       int setIPv6PrivacyExtensions(const char *interface, const int on);
-       int setIPv6NdOffload(char* interface, const int on);
-       int setMtu(const char *interface, const char *mtu);
+public:
+    static void initializeAll();
 
- private:
-       void setAcceptRA(const char* value);
-       void setAcceptRARouteTable(int tableOrOffset);
-       void setBaseReachableTimeMs(unsigned int millis);
-       void setIPv6OptimisticMode(const char *value);
+    static int setEnableIPv6(const char *interface, const int on);
+    static int setAcceptIPv6Ra(const char *interface, const int on);
+    static int setAcceptIPv6Dad(const char *interface, const int on);
+    static int setIPv6PrivacyExtensions(const char *interface, const int on);
+    static int setIPv6NdOffload(char* interface, const int on);
+    static int setMtu(const char *interface, const char *mtu);
+
+private:
+    static void setAcceptRA(const char* value);
+    static void setAcceptRARouteTable(int tableOrOffset);
+    static void setBaseReachableTimeMs(unsigned int millis);
+    static void setIPv6OptimisticMode(const char *value);
+
+    InterfaceController() = delete;
+    ~InterfaceController() = delete;
 };
 
 #endif
index dbbd933..971104f 100644 (file)
 #include "Fwmark.h"
 #include "NetdConstants.h"
 #include "Permission.h"
+#include "InterfaceController.h"
 #include "TetherController.h"
 
 namespace {
 
-static const char BP_TOOLS_MODE[] = "bp-tools";
-static const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
-static const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
-static const char SEPARATOR[] = "|";
+const char BP_TOOLS_MODE[] = "bp-tools";
+const char IPV4_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv4/ip_forward";
+const char IPV6_FORWARDING_PROC_FILE[] = "/proc/sys/net/ipv6/conf/all/forwarding";
+const char SEPARATOR[] = "|";
 
 bool writeToFile(const char* filename, const char* value) {
     int fd = open(filename, O_WRONLY);
@@ -61,6 +62,17 @@ bool writeToFile(const char* filename, const char* value) {
     return true;
 }
 
+bool configureForIPv6Router(const char *interface) {
+    return (InterfaceController::setEnableIPv6(interface, 0) == 0)
+            && (InterfaceController::setAcceptIPv6Ra(interface, 0) == 0)
+            && (InterfaceController::setEnableIPv6(interface, 1) == 0);
+}
+
+void configureForIPv6Client(const char *interface) {
+    InterfaceController::setAcceptIPv6Ra(interface, 1);
+    InterfaceController::setEnableIPv6(interface, 0);
+}
+
 bool inBpToolsMode() {
     // In BP tools mode, do not disable IP forwarding
     char bootmode[PROPERTY_VALUE_MAX] = {0};
@@ -71,9 +83,7 @@ bool inBpToolsMode() {
 }  // namespace
 
 TetherController::TetherController() {
-    mInterfaces = new InterfaceCollection();
     mDnsNetId = 0;
-    mDnsForwarders = new NetAddressCollection();
     mDaemonFd = -1;
     mDaemonPid = 0;
     if (inBpToolsMode()) {
@@ -84,14 +94,8 @@ TetherController::TetherController() {
 }
 
 TetherController::~TetherController() {
-    InterfaceCollection::iterator it;
-
-    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
-        free(*it);
-    }
-    mInterfaces->clear();
-
-    mDnsForwarders->clear();
+    mInterfaces.clear();
+    mDnsForwarders.clear();
     mForwardingRequests.clear();
 }
 
@@ -233,7 +237,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
     snprintf(daemonCmd, sizeof(daemonCmd), "update_dns%s0x%x", SEPARATOR, fwmark.intValue);
     int cmdLen = strlen(daemonCmd);
 
-    mDnsForwarders->clear();
+    mDnsForwarders.clear();
     for (i = 0; i < numServers; i++) {
         ALOGD("setDnsForwarders(0x%x %d = '%s')", fwmark.intValue, i, servers[i]);
 
@@ -242,7 +246,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
         freeaddrinfo(res);
         if (ret) {
             ALOGE("Failed to parse DNS server '%s'", servers[i]);
-            mDnsForwarders->clear();
+            mDnsForwarders.clear();
             errno = EINVAL;
             return -1;
         }
@@ -255,7 +259,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
 
         strcat(daemonCmd, SEPARATOR);
         strcat(daemonCmd, servers[i]);
-        mDnsForwarders->push_back(servers[i]);
+        mDnsForwarders.push_back(servers[i]);
     }
 
     mDnsNetId = netId;
@@ -263,7 +267,7 @@ int TetherController::setDnsForwarders(unsigned netId, char **servers, int numSe
         ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
         if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
             ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
-            mDnsForwarders->clear();
+            mDnsForwarders.clear();
             errno = EREMOTEIO;
             return -1;
         }
@@ -275,27 +279,26 @@ unsigned TetherController::getDnsNetId() {
     return mDnsNetId;
 }
 
-NetAddressCollection *TetherController::getDnsForwarders() {
+const std::list<std::string> &TetherController::getDnsForwarders() const {
     return mDnsForwarders;
 }
 
-int TetherController::applyDnsInterfaces() {
+bool TetherController::applyDnsInterfaces() {
     char daemonCmd[MAX_CMD_SIZE];
 
     strcpy(daemonCmd, "update_ifaces");
     int cmdLen = strlen(daemonCmd);
-    InterfaceCollection::iterator it;
     bool haveInterfaces = false;
 
-    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
-        cmdLen += (strlen(*it) + 1);
+    for (const auto &ifname : mInterfaces) {
+        cmdLen += (ifname.size() + 1);
         if (cmdLen + 1 >= MAX_CMD_SIZE) {
             ALOGD("Too many DNS ifaces listed");
             break;
         }
 
         strcat(daemonCmd, SEPARATOR);
-        strcat(daemonCmd, *it);
+        strcat(daemonCmd, ifname.c_str());
         haveInterfaces = true;
     }
 
@@ -303,10 +306,10 @@ int TetherController::applyDnsInterfaces() {
         ALOGD("Sending update msg to dnsmasq [%s]", daemonCmd);
         if (write(mDaemonFd, daemonCmd, strlen(daemonCmd) +1) < 0) {
             ALOGE("Failed to send update command to dnsmasq (%s)", strerror(errno));
-            return -1;
+            return false;
         }
     }
-    return 0;
+    return true;
 }
 
 int TetherController::tetherInterface(const char *interface) {
@@ -315,17 +318,16 @@ int TetherController::tetherInterface(const char *interface) {
         errno = ENOENT;
         return -1;
     }
-    mInterfaces->push_back(strdup(interface));
-
-    if (applyDnsInterfaces()) {
-        InterfaceCollection::iterator it;
-        for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
-            if (!strcmp(interface, *it)) {
-                free(*it);
-                mInterfaces->erase(it);
-                break;
-            }
-        }
+
+    if (!configureForIPv6Router(interface)) {
+        configureForIPv6Client(interface);
+        return -1;
+    }
+    mInterfaces.push_back(interface);
+
+    if (!applyDnsInterfaces()) {
+        mInterfaces.pop_back();
+        configureForIPv6Client(interface);
         return -1;
     } else {
         return 0;
@@ -333,22 +335,20 @@ int TetherController::tetherInterface(const char *interface) {
 }
 
 int TetherController::untetherInterface(const char *interface) {
-    InterfaceCollection::iterator it;
-
     ALOGD("untetherInterface(%s)", interface);
 
-    for (it = mInterfaces->begin(); it != mInterfaces->end(); ++it) {
-        if (!strcmp(interface, *it)) {
-            free(*it);
-            mInterfaces->erase(it);
+    for (auto it = mInterfaces.cbegin(); it != mInterfaces.cend(); ++it) {
+        if (!strcmp(interface, it->c_str())) {
+            mInterfaces.erase(it);
 
-            return applyDnsInterfaces();
+            configureForIPv6Client(interface);
+            return applyDnsInterfaces() ? 0 : -1;
         }
     }
     errno = ENOENT;
     return -1;
 }
 
-InterfaceCollection *TetherController::getTetheredInterfaceList() {
+const std::list<std::string> &TetherController::getTetheredInterfaceList() const {
     return mInterfaces;
 }
index 0aa19f2..6035c25 100644 (file)
 #include <set>
 #include <string>
 
-typedef std::list<char *> InterfaceCollection;
-typedef std::list<std::string> NetAddressCollection;
 
 class TetherController {
-    InterfaceCollection  *mInterfaces;
+private:
+    std::list<std::string> mInterfaces;
     // NetId to use for forwarded DNS queries. This may not be the default
     // network, e.g., in the case where we are tethering to a DUN APN.
-    unsigned              mDnsNetId;
-    NetAddressCollection *mDnsForwarders;
-    pid_t                 mDaemonPid;
-    int                   mDaemonFd;
-    std::set<std::string> mForwardingRequests;
+    unsigned               mDnsNetId;
+    std::list<std::string> mDnsForwarders;
+    pid_t                  mDaemonPid;
+    int                    mDaemonFd;
+    std::set<std::string>  mForwardingRequests;
 
 public:
     TetherController();
@@ -50,14 +49,14 @@ public:
 
     unsigned getDnsNetId();
     int setDnsForwarders(unsigned netId, char **servers, int numServers);
-    NetAddressCollection *getDnsForwarders();
+    const std::list<std::string> &getDnsForwarders() const;
 
     int tetherInterface(const char *interface);
     int untetherInterface(const char *interface);
-    InterfaceCollection *getTetheredInterfaceList();
+    const std::list<std::string> &getTetheredInterfaceList() const;
 
 private:
-    int applyDnsInterfaces();
+    bool applyDnsInterfaces();
     bool setIpFwdEnabled();
 };