12eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt/* 22eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Copyright (C) 2012 The Android Open Source Project 32eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 42eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Licensed under the Apache License, Version 2.0 (the "License"); 52eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * you may not use this file except in compliance with the License. 62eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * You may obtain a copy of the License at 72eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 8329c3b4681e2ca4831adc7c8cf257e9e32971710Sasha Levitskiy * http://www.apache.org/licenses/LICENSE-2.0 92eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * 102eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * Unless required by applicable law or agreed to in writing, software 112eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * distributed under the License is distributed on an "AS IS" BASIS, 122eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * See the License for the specific language governing permissions and 142eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt * limitations under the License. 152eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt */ 162eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 1737f2e371c43588ca3661584a79b6544de345189aLorenzo Colitti#include <dirent.h> 18aa1be2b3d24d99f3ccb98ff4fbb2a81b63587effDan Albert#include <errno.h> 195f4938fea4170d251a3eb23ffc6239cfd1604cc8Elliott Hughes#include <malloc.h> 20b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline#include <sys/socket.h> 212eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 2231e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz#include <functional> 2331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz 242eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#define LOG_TAG "InterfaceController" 25bbd5626b3d0994ff0ecbfceac75f6dc4abfb55c6Elliott Hughes#include <android-base/file.h> 26bbd5626b3d0994ff0ecbfceac75f6dc4abfb55c6Elliott Hughes#include <android-base/stringprintf.h> 272eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include <cutils/log.h> 280ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti#include <logwrap/logwrap.h> 29c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline#include <netutils/ifc.h> 3070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti 312eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt#include "InterfaceController.h" 32a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran#include "RouteController.h" 332eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt 345407e14fd3d81bb76f94221b4a359faa2806de65Dan Albertusing android::base::StringPrintf; 35b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineusing android::base::ReadFileToString; 365407e14fd3d81bb76f94221b4a359faa2806de65Dan Albertusing android::base::WriteStringToFile; 377035f228d17e925116b1b64a7c917b3196ab8818Lorenzo Colittiusing android::net::RouteController; 385407e14fd3d81bb76f94221b4a359faa2806de65Dan Albert 39e1da484b30196cc6ec496407e32c67bcb5295becErik Klinenamespace { 40e1da484b30196cc6ec496407e32c67bcb5295becErik Kline 4137f2e371c43588ca3661584a79b6544de345189aLorenzo Colitticonst char ipv6_proc_path[] = "/proc/sys/net/ipv6/conf"; 4237f2e371c43588ca3661584a79b6544de345189aLorenzo Colitti 43145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Klineconst char ipv4_neigh_conf_dir[] = "/proc/sys/net/ipv4/neigh"; 44145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline 45145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Klineconst char ipv6_neigh_conf_dir[] = "/proc/sys/net/ipv6/neigh"; 46145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline 47b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineconst char proc_net_path[] = "/proc/sys/net"; 486d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidtconst char sys_net_path[] = "/sys/class/net"; 496d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt 50bdcba1127a8709566fdec49bc303234e0e8ee924Erik Klineconst char wl_util_path[] = "/vendor/xbin/wlutil"; 510ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti 5231e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelzconstexpr int kRouteInfoMinPrefixLen = 48; 5331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz 5431e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz// RFC 7421 prefix length. 5531e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelzconstexpr int kRouteInfoMaxPrefixLen = 64; 5631e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz 57b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineinline bool isNormalPathComponent(const char *component) { 58b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return (strcmp(component, ".") != 0) && 59b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline (strcmp(component, "..") != 0) && 60b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline (strchr(component, '/') == nullptr); 61b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline} 62b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline 63b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineinline bool isAddressFamilyPathComponent(const char *component) { 64b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return strcmp(component, "ipv4") == 0 || strcmp(component, "ipv6") == 0; 65b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline} 66b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline 67b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineinline bool isInterfaceName(const char *name) { 68b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return isNormalPathComponent(name) && 69b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline (strcmp(name, "default") != 0) && 70b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline (strcmp(name, "all") != 0); 71e1da484b30196cc6ec496407e32c67bcb5295becErik Kline} 72e1da484b30196cc6ec496407e32c67bcb5295becErik Kline 73e1da484b30196cc6ec496407e32c67bcb5295becErik Klineint writeValueToPath( 74e1da484b30196cc6ec496407e32c67bcb5295becErik Kline const char* dirname, const char* subdirname, const char* basename, 75e1da484b30196cc6ec496407e32c67bcb5295becErik Kline const char* value) { 76e1da484b30196cc6ec496407e32c67bcb5295becErik Kline std::string path(StringPrintf("%s/%s/%s", dirname, subdirname, basename)); 773f95777d2aafa6c0ac4671d55557cad0d04a223fErik Kline return WriteStringToFile(value, path) ? 0 : -1; 78e1da484b30196cc6ec496407e32c67bcb5295becErik Kline} 79e1da484b30196cc6ec496407e32c67bcb5295becErik Kline 8031e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz// Run @fn on each interface as well as 'default' in the path @dirname. 8131e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelzvoid forEachInterface(const std::string& dirname, 8231e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz std::function<void(const std::string& path, const std::string& iface)> fn) { 8331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz // Run on default, which controls the behavior of any interfaces that are created in the future. 8431e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz fn(dirname, "default"); 8531e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz DIR* dir = opendir(dirname.c_str()); 86e1da484b30196cc6ec496407e32c67bcb5295becErik Kline if (!dir) { 8731e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz ALOGE("Can't list %s: %s", dirname.c_str(), strerror(errno)); 88e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return; 89e1da484b30196cc6ec496407e32c67bcb5295becErik Kline } 9031e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz while (true) { 9131e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz const dirent *ent = readdir(dir); 9231e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz if (!ent) { 9331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz break; 9431e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz } 9531e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz if ((ent->d_type != DT_DIR) || !isInterfaceName(ent->d_name)) { 96e1da484b30196cc6ec496407e32c67bcb5295becErik Kline continue; 97e1da484b30196cc6ec496407e32c67bcb5295becErik Kline } 9831e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz fn(dirname, ent->d_name); 99e1da484b30196cc6ec496407e32c67bcb5295becErik Kline } 100e1da484b30196cc6ec496407e32c67bcb5295becErik Kline closedir(dir); 101e1da484b30196cc6ec496407e32c67bcb5295becErik Kline} 102e1da484b30196cc6ec496407e32c67bcb5295becErik Kline 10331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelzvoid setOnAllInterfaces(const char* dirname, const char* basename, const char* value) { 10431e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz auto fn = [basename, value](const std::string& path, const std::string& iface) { 10531e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz writeValueToPath(path.c_str(), iface.c_str(), basename, value); 10631e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz }; 10731e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz forEachInterface(dirname, fn); 10831e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz} 10931e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz 1107adf8d71b80a729354c358d7a0110651750db5f2Erik Klinevoid setIPv6UseOutgoingInterfaceAddrsOnly(const char *value) { 1117adf8d71b80a729354c358d7a0110651750db5f2Erik Kline setOnAllInterfaces(ipv6_proc_path, "use_oif_addrs_only", value); 1127adf8d71b80a729354c358d7a0110651750db5f2Erik Kline} 1137adf8d71b80a729354c358d7a0110651750db5f2Erik Kline 114b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klinestd::string getParameterPathname( 115b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline const char *family, const char *which, const char *interface, const char *parameter) { 116b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline if (!isAddressFamilyPathComponent(family)) { 117b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline errno = EAFNOSUPPORT; 118b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return ""; 119b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline } else if (!isNormalPathComponent(which) || 120b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline !isInterfaceName(interface) || 121b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline !isNormalPathComponent(parameter)) { 122b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline errno = EINVAL; 123b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return ""; 124b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline } 125b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline 126b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return StringPrintf("%s/%s/%s/%s/%s", proc_net_path, family, which, interface, parameter); 127b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline} 128b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline 12931e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelzvoid setAcceptIPv6RIO(int min, int max) { 13031e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz auto fn = [min, max](const std::string& prefix, const std::string& iface) { 13131e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz int rv = writeValueToPath(prefix.c_str(), iface.c_str(), "accept_ra_rt_info_min_plen", 13231e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz std::to_string(min).c_str()); 13331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz if (rv != 0) { 13431e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz // Only update max_plen if the write to min_plen succeeded. This ordering will prevent 13531e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz // RIOs from being accepted unless both min and max are written successfully. 13631e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz return; 13731e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz } 13831e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz writeValueToPath(prefix.c_str(), iface.c_str(), "accept_ra_rt_info_max_plen", 13931e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz std::to_string(max).c_str()); 14031e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz }; 14131e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz forEachInterface(ipv6_proc_path, fn); 14231e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz} 14331e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz 144e1da484b30196cc6ec496407e32c67bcb5295becErik Kline} // namespace 145e1da484b30196cc6ec496407e32c67bcb5295becErik Kline 1462c5aaa1876db659556c2e9605beccc670e6b7c0dErik Klinevoid InterfaceController::initializeAll() { 1472c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // Initial IPv6 settings. 1482c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // By default, accept_ra is set to 1 (accept RAs unless forwarding is on) on all interfaces. 1492c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // This causes RAs to work or not work based on whether forwarding is on, and causes routes 1502c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // learned from RAs to go away when forwarding is turned on. Make this behaviour predictable 1512c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // by always setting accept_ra to 2. 1522c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline setAcceptRA("2"); 15337f2e371c43588ca3661584a79b6544de345189aLorenzo Colitti 15431e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz // Accept RIOs with prefix length in the closed interval [48, 64]. 15531e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz setAcceptIPv6RIO(kRouteInfoMinPrefixLen, kRouteInfoMaxPrefixLen); 15631e2599eeae7bc06b2ab4293a1a24b01d03512bcJoel Scherpelz 1572c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline setAcceptRARouteTable(-RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX); 15859273ede02fc91d2a3297547d959159c8c6f69f3Erik Kline 1592c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // Enable optimistic DAD for IPv6 addresses on all interfaces. 1602c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline setIPv6OptimisticMode("1"); 161145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline 1622c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // Reduce the ARP/ND base reachable time from the default (30sec) to 15sec. 1632c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline setBaseReachableTimeMs(15 * 1000); 1647adf8d71b80a729354c358d7a0110651750db5f2Erik Kline 1652c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // When sending traffic via a given interface use only addresses configured 1662c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // on that interface as possible source addresses. 1672c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline setIPv6UseOutgoingInterfaceAddrsOnly("1"); 1682eab1f762badb7ba46b95716e62ea4548a979903Dmitry Shmidt} 16970afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti 17070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colittiint InterfaceController::setEnableIPv6(const char *interface, const int on) { 171e1da484b30196cc6ec496407e32c67bcb5295becErik Kline if (!isIfaceName(interface)) { 172e1da484b30196cc6ec496407e32c67bcb5295becErik Kline errno = ENOENT; 173e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return -1; 174e1da484b30196cc6ec496407e32c67bcb5295becErik Kline } 175e1da484b30196cc6ec496407e32c67bcb5295becErik Kline // When disable_ipv6 changes from 1 to 0, the kernel starts autoconf. 176e1da484b30196cc6ec496407e32c67bcb5295becErik Kline // When disable_ipv6 changes from 0 to 1, the kernel clears all autoconf 177e1da484b30196cc6ec496407e32c67bcb5295becErik Kline // addresses and routes and disables IPv6 on the interface. 178e1da484b30196cc6ec496407e32c67bcb5295becErik Kline const char *disable_ipv6 = on ? "0" : "1"; 179e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return writeValueToPath(ipv6_proc_path, interface, "disable_ipv6", disable_ipv6); 18070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti} 18170afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti 1822c5aaa1876db659556c2e9605beccc670e6b7c0dErik Klineint InterfaceController::setAcceptIPv6Ra(const char *interface, const int on) { 1832c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline if (!isIfaceName(interface)) { 1842c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline errno = ENOENT; 1852c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline return -1; 1862c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline } 1872c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // Because forwarding can be enabled even when tethering is off, we always 1882c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline // use mode "2" (accept RAs, even if forwarding is enabled). 1892c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline const char *accept_ra = on ? "2" : "0"; 1902c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline return writeValueToPath(ipv6_proc_path, interface, "accept_ra", accept_ra); 1912c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline} 1922c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline 1932c5aaa1876db659556c2e9605beccc670e6b7c0dErik Klineint InterfaceController::setAcceptIPv6Dad(const char *interface, const int on) { 1942c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline if (!isIfaceName(interface)) { 1952c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline errno = ENOENT; 1962c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline return -1; 1972c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline } 1982c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline const char *accept_dad = on ? "1" : "0"; 1992c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline return writeValueToPath(ipv6_proc_path, interface, "accept_dad", accept_dad); 2002c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline} 2012c5aaa1876db659556c2e9605beccc670e6b7c0dErik Kline 20259d8c48cee74679d2305c535ab61d4a6f8258c64Erik Klineint InterfaceController::setIPv6DadTransmits(const char *interface, const char *value) { 20359d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline if (!isIfaceName(interface)) { 20459d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline errno = ENOENT; 20559d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline return -1; 20659d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline } 20759d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline return writeValueToPath(ipv6_proc_path, interface, "dad_transmits", value); 20859d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline} 20959d8c48cee74679d2305c535ab61d4a6f8258c64Erik Kline 21070afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colittiint InterfaceController::setIPv6PrivacyExtensions(const char *interface, const int on) { 211e1da484b30196cc6ec496407e32c67bcb5295becErik Kline if (!isIfaceName(interface)) { 212e1da484b30196cc6ec496407e32c67bcb5295becErik Kline errno = ENOENT; 213e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return -1; 214e1da484b30196cc6ec496407e32c67bcb5295becErik Kline } 215e1da484b30196cc6ec496407e32c67bcb5295becErik Kline // 0: disable IPv6 privacy addresses 216e1da484b30196cc6ec496407e32c67bcb5295becErik Kline // 0: enable IPv6 privacy addresses and prefer them over non-privacy ones. 217e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return writeValueToPath(ipv6_proc_path, interface, "use_tempaddr", on ? "2" : "0"); 21870afde6ad9b5fce63cca594ac9b230d2fc9b21eeLorenzo Colitti} 21937f2e371c43588ca3661584a79b6544de345189aLorenzo Colitti 2200ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti// Enables or disables IPv6 ND offload. This is useful for 464xlat on wifi, IPv6 tethering, and 2210ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti// generally implementing IPv6 neighbour discovery and duplicate address detection properly. 2220ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti// TODO: This should be implemented in wpa_supplicant via driver commands instead. 2230ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colittiint InterfaceController::setIPv6NdOffload(char* interface, const int on) { 2240ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti // Only supported on Broadcom chipsets via wlutil for now. 2250ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti if (access(wl_util_path, X_OK) == 0) { 2260ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti const char *argv[] = { 2270ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti wl_util_path, 2280ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti "-a", 2290ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti interface, 2300ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti "ndoe", 2310ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti on ? "1" : "0" 2320ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti }; 2330ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti int ret = android_fork_execvp(ARRAY_SIZE(argv), const_cast<char**>(argv), NULL, 2340ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti false, false); 2350ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti ALOGD("%s ND offload on %s: %d (%s)", 2360ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti (on ? "enabling" : "disabling"), interface, ret, strerror(errno)); 2370ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti return ret; 2380ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti } else { 2390ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti return 0; 2400ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti } 2410ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti} 2420ea8ff87012f6bda41b6d2b4629d4fd0fd6f4794Lorenzo Colitti 243a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandranvoid InterfaceController::setAcceptRA(const char *value) { 244e1da484b30196cc6ec496407e32c67bcb5295becErik Kline setOnAllInterfaces(ipv6_proc_path, "accept_ra", value); 245a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran} 246a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran 247a01d6eff4316c6c10e81bd8d48ae85aa82b933e3Sreeram Ramachandran// |tableOrOffset| is interpreted as: 248a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran// If == 0: default. Routes go into RT6_TABLE_MAIN. 249a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran// If > 0: user set. Routes go into the specified table. 250a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran// If < 0: automatic. The absolute value is intepreted as an offset and added to the interface 251a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran// ID to get the table. If it's set to -1000, routes from interface ID 5 will go into 252a48118062412f16ae712bfc8c8a539d3b6a85e47Sreeram Ramachandran// table 1005, etc. 253a01d6eff4316c6c10e81bd8d48ae85aa82b933e3Sreeram Ramachandranvoid InterfaceController::setAcceptRARouteTable(int tableOrOffset) { 254e1da484b30196cc6ec496407e32c67bcb5295becErik Kline std::string value(StringPrintf("%d", tableOrOffset)); 255e1da484b30196cc6ec496407e32c67bcb5295becErik Kline setOnAllInterfaces(ipv6_proc_path, "accept_ra_rt_table", value.c_str()); 25637f2e371c43588ca3661584a79b6544de345189aLorenzo Colitti} 2576d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt 2586d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidtint InterfaceController::setMtu(const char *interface, const char *mtu) 2596d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt{ 260e1da484b30196cc6ec496407e32c67bcb5295becErik Kline if (!isIfaceName(interface)) { 261e1da484b30196cc6ec496407e32c67bcb5295becErik Kline errno = ENOENT; 262e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return -1; 263e1da484b30196cc6ec496407e32c67bcb5295becErik Kline } 264e1da484b30196cc6ec496407e32c67bcb5295becErik Kline return writeValueToPath(sys_net_path, interface, "mtu", mtu); 2656d6c0e6f1164e3182538cb48c2b95d90a2eb780cDmitry Shmidt} 26659273ede02fc91d2a3297547d959159c8c6f69f3Erik Kline 267c296f098b63a986265ded8adf13118ba512a0fa7Erik Klineint InterfaceController::addAddress(const char *interface, 268c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline const char *addrString, int prefixLength) { 269c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline return ifc_add_address(interface, addrString, prefixLength); 270c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline} 271c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline 272c296f098b63a986265ded8adf13118ba512a0fa7Erik Klineint InterfaceController::delAddress(const char *interface, 273c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline const char *addrString, int prefixLength) { 274c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline return ifc_del_address(interface, addrString, prefixLength); 275c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline} 276c296f098b63a986265ded8adf13118ba512a0fa7Erik Kline 277b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineint InterfaceController::getParameter( 278b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline const char *family, const char *which, const char *interface, const char *parameter, 279b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline std::string *value) { 280b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline const std::string path(getParameterPathname(family, which, interface, parameter)); 281b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline if (path.empty()) { 282b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return -errno; 283b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline } 284b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return ReadFileToString(path, value) ? 0 : -errno; 285b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline} 286b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline 287b218a87e0777d3d2c93231e03ef7315d783e3279Erik Klineint InterfaceController::setParameter( 288b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline const char *family, const char *which, const char *interface, const char *parameter, 289b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline const char *value) { 290b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline const std::string path(getParameterPathname(family, which, interface, parameter)); 291b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline if (path.empty()) { 292b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return -errno; 293b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline } 294b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline return WriteStringToFile(value, path) ? 0 : -errno; 295b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline} 296b218a87e0777d3d2c93231e03ef7315d783e3279Erik Kline 297145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Klinevoid InterfaceController::setBaseReachableTimeMs(unsigned int millis) { 298145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline std::string value(StringPrintf("%u", millis)); 299145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline setOnAllInterfaces(ipv4_neigh_conf_dir, "base_reachable_time_ms", value.c_str()); 300145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline setOnAllInterfaces(ipv6_neigh_conf_dir, "base_reachable_time_ms", value.c_str()); 301145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline} 302145fd25509e08fb2d76fcff8d011e1aa9a2e6455Erik Kline 30359273ede02fc91d2a3297547d959159c8c6f69f3Erik Klinevoid InterfaceController::setIPv6OptimisticMode(const char *value) { 304e1da484b30196cc6ec496407e32c67bcb5295becErik Kline setOnAllInterfaces(ipv6_proc_path, "optimistic_dad", value); 305e1da484b30196cc6ec496407e32c67bcb5295becErik Kline setOnAllInterfaces(ipv6_proc_path, "use_optimistic", value); 30659273ede02fc91d2a3297547d959159c8c6f69f3Erik Kline} 307