Add general /proc/sys/net/ipv[46]/{conf,neigh}/ interface
Bug: 21859053
Bug: 28135208
Change-Id: Ia3232706a697fd149ed87f74586efe3d434261f8
diff --git a/server/InterfaceController.cpp b/server/InterfaceController.cpp
index eac4fbf..1d0a8e0 100644
--- a/server/InterfaceController.cpp
+++ b/server/InterfaceController.cpp
@@ -17,6 +17,7 @@
#include <dirent.h>
#include <errno.h>
#include <malloc.h>
+#include <sys/socket.h>
#define LOG_TAG "InterfaceController"
#include <android-base/file.h>
@@ -29,6 +30,7 @@
#include "RouteController.h"
using android::base::StringPrintf;
+using android::base::ReadFileToString;
using android::base::WriteStringToFile;
namespace {
@@ -39,15 +41,25 @@
const char ipv6_neigh_conf_dir[] = "/proc/sys/net/ipv6/neigh";
+const char proc_net_path[] = "/proc/sys/net";
const char sys_net_path[] = "/sys/class/net";
const char wl_util_path[] = "/vendor/xbin/wlutil";
-bool isInterfaceName(const char *name) {
- return strcmp(name, ".") &&
- strcmp(name, "..") &&
- strcmp(name, "default") &&
- strcmp(name, "all");
+inline bool isNormalPathComponent(const char *component) {
+ return (strcmp(component, ".") != 0) &&
+ (strcmp(component, "..") != 0) &&
+ (strchr(component, '/') == nullptr);
+}
+
+inline bool isAddressFamilyPathComponent(const char *component) {
+ return strcmp(component, "ipv4") == 0 || strcmp(component, "ipv6") == 0;
+}
+
+inline bool isInterfaceName(const char *name) {
+ return isNormalPathComponent(name) &&
+ (strcmp(name, "default") != 0) &&
+ (strcmp(name, "all") != 0);
}
int writeValueToPath(
@@ -81,6 +93,21 @@
setOnAllInterfaces(ipv6_proc_path, "use_oif_addrs_only", value);
}
+std::string getParameterPathname(
+ const char *family, const char *which, const char *interface, const char *parameter) {
+ if (!isAddressFamilyPathComponent(family)) {
+ errno = EAFNOSUPPORT;
+ return "";
+ } else if (!isNormalPathComponent(which) ||
+ !isInterfaceName(interface) ||
+ !isNormalPathComponent(parameter)) {
+ errno = EINVAL;
+ return "";
+ }
+
+ return StringPrintf("%s/%s/%s/%s/%s", proc_net_path, family, which, interface, parameter);
+}
+
} // namespace
void InterfaceController::initializeAll() {
@@ -201,7 +228,6 @@
return writeValueToPath(sys_net_path, interface, "mtu", mtu);
}
-
int InterfaceController::addAddress(const char *interface,
const char *addrString, int prefixLength) {
return ifc_add_address(interface, addrString, prefixLength);
@@ -212,6 +238,26 @@
return ifc_del_address(interface, addrString, prefixLength);
}
+int InterfaceController::getParameter(
+ const char *family, const char *which, const char *interface, const char *parameter,
+ std::string *value) {
+ const std::string path(getParameterPathname(family, which, interface, parameter));
+ if (path.empty()) {
+ return -errno;
+ }
+ return ReadFileToString(path, value) ? 0 : -errno;
+}
+
+int InterfaceController::setParameter(
+ const char *family, const char *which, const char *interface, const char *parameter,
+ const char *value) {
+ const std::string path(getParameterPathname(family, which, interface, parameter));
+ if (path.empty()) {
+ return -errno;
+ }
+ return WriteStringToFile(value, path) ? 0 : -errno;
+}
+
void InterfaceController::setBaseReachableTimeMs(unsigned int millis) {
std::string value(StringPrintf("%u", millis));
setOnAllInterfaces(ipv4_neigh_conf_dir, "base_reachable_time_ms", value.c_str());