Implement INetd.aidl getProcSysNet().
Also: a few "tidy-inspired" changes.
Test: as follows
- built, flashed, booted
- system/netd/tests/runtest.sh passes
Bug: 32163131
Change-Id: Icaa164af3c3d0d03af1ec083dfcbe856ac51529f
diff --git a/server/InterfaceController.cpp b/server/InterfaceController.cpp
index 34b8004..4c35085 100644
--- a/server/InterfaceController.cpp
+++ b/server/InterfaceController.cpp
@@ -26,6 +26,7 @@
#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
#include <log/log.h>
#include <logwrap/logwrap.h>
#include <netutils/ifc.h>
@@ -40,17 +41,18 @@
using android::base::ReadFileToString;
using android::base::StringPrintf;
+using android::base::Trim;
using android::base::WriteStringToFile;
using android::net::INetd;
using android::net::RouteController;
using android::netdutils::isOk;
-using android::netdutils::Status;
-using android::netdutils::StatusOr;
using android::netdutils::makeSlice;
using android::netdutils::sSyscalls;
-using android::netdutils::status::ok;
+using android::netdutils::Status;
using android::netdutils::statusFromErrno;
+using android::netdutils::StatusOr;
using android::netdutils::toString;
+using android::netdutils::status::ok;
namespace {
@@ -380,7 +382,11 @@
if (path.empty()) {
return -errno;
}
- return ReadFileToString(path, value) ? 0 : -errno;
+ if (ReadFileToString(path, value)) {
+ *value = Trim(*value);
+ return 0;
+ }
+ return -errno;
}
int InterfaceController::setParameter(
diff --git a/server/InterfaceController.h b/server/InterfaceController.h
index 58505a6..45ff878 100644
--- a/server/InterfaceController.h
+++ b/server/InterfaceController.h
@@ -47,6 +47,9 @@
// Read and write values in files of the form:
// /proc/sys/net/<family>/<which>/<interface>/<parameter>
+ //
+ // NOTE: getParameter() trims whitespace so the caller does not need extra
+ // code to crop trailing newlines, for example.
static int getParameter(
const char *family, const char *which, const char *interface, const char *parameter,
std::string *value);
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index c0ca209..cb974ea 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "Netd"
#include <set>
+#include <tuple>
#include <vector>
#include <android-base/stringprintf.h>
@@ -444,25 +445,25 @@
return binder::Status::ok();
}
-binder::Status NetdNativeService::setProcSysNet(
- int32_t family, int32_t which, const std::string &ifname, const std::string ¶meter,
- const std::string &value) {
- ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
+namespace {
- const char *familyStr;
- switch (family) {
+std::tuple<binder::Status, const char*, const char*> getPathComponents(int32_t ipversion,
+ int32_t category) {
+ const char* ipversionStr = nullptr;
+ switch (ipversion) {
case INetd::IPV4:
- familyStr = "ipv4";
+ ipversionStr = "ipv4";
break;
case INetd::IPV6:
- familyStr = "ipv6";
+ ipversionStr = "ipv6";
break;
default:
- return binder::Status::fromServiceSpecificError(EAFNOSUPPORT, String8("Bad family"));
+ return {binder::Status::fromServiceSpecificError(EAFNOSUPPORT, "Bad IP version"),
+ nullptr, nullptr};
}
- const char *whichStr;
- switch (which) {
+ const char* whichStr = nullptr;
+ switch (category) {
case INetd::CONF:
whichStr = "conf";
break;
@@ -470,17 +471,58 @@
whichStr = "neigh";
break;
default:
- return binder::Status::fromServiceSpecificError(EINVAL, String8("Bad category"));
+ return {binder::Status::fromServiceSpecificError(EINVAL, "Bad category"), nullptr,
+ nullptr};
}
- const int err = InterfaceController::setParameter(
- familyStr, whichStr, ifname.c_str(), parameter.c_str(),
- value.c_str());
- if (err != 0) {
- return binder::Status::fromServiceSpecificError(-err,
- String8::format("ResolverController error: %s", strerror(-err)));
+ return {binder::Status::ok(), ipversionStr, whichStr};
+}
+
+} // namespace
+
+binder::Status NetdNativeService::getProcSysNet(int32_t ipversion, int32_t which,
+ const std::string& ifname,
+ const std::string& parameter, std::string* value) {
+ ENFORCE_PERMISSION(NETWORK_STACK);
+ auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__)
+ .args(ipversion, which, ifname, parameter);
+
+ const auto pathParts = getPathComponents(ipversion, which);
+ const auto& pathStatus = std::get<0>(pathParts);
+ if (!pathStatus.isOk()) {
+ gLog.log(entry.returns(pathStatus.exceptionCode()).withAutomaticDuration());
+ return pathStatus;
}
- return binder::Status::ok();
+
+ const int err = InterfaceController::getParameter(std::get<1>(pathParts),
+ std::get<2>(pathParts), ifname.c_str(),
+ parameter.c_str(), value);
+ entry.returns(err);
+ if (err == 0) entry.returns(*value);
+ gLog.log(entry.withAutomaticDuration());
+ return statusFromErrcode(err);
+}
+
+binder::Status NetdNativeService::setProcSysNet(int32_t ipversion, int32_t which,
+ const std::string& ifname,
+ const std::string& parameter,
+ const std::string& value) {
+ ENFORCE_PERMISSION(NETWORK_STACK);
+ auto entry = gLog.newEntry().prettyFunction(__PRETTY_FUNCTION__)
+ .args(ipversion, which, ifname, parameter, value);
+
+ const auto pathParts = getPathComponents(ipversion, which);
+ const auto& pathStatus = std::get<0>(pathParts);
+ if (!pathStatus.isOk()) {
+ gLog.log(entry.returns(pathStatus.exceptionCode()).withAutomaticDuration());
+ return pathStatus;
+ }
+
+ const int err = InterfaceController::setParameter(std::get<1>(pathParts),
+ std::get<2>(pathParts), ifname.c_str(),
+ parameter.c_str(), value.c_str());
+ gLog.log(entry.returns(err).withAutomaticDuration());
+ return statusFromErrcode(err);
}
binder::Status NetdNativeService::getMetricsReportingLevel(int *reportingLevel) {
diff --git a/server/NetdNativeService.h b/server/NetdNativeService.h
index b34e363..c8b85f0 100644
--- a/server/NetdNativeService.h
+++ b/server/NetdNativeService.h
@@ -93,9 +93,10 @@
binder::Status interfaceDelAddress(const std::string &ifName,
const std::string &addrString, int prefixLength) override;
- binder::Status setProcSysNet(
- int32_t family, int32_t which, const std::string &ifname, const std::string ¶meter,
- const std::string &value) override;
+ binder::Status getProcSysNet(int32_t ipversion, int32_t which, const std::string& ifname,
+ const std::string& parameter, std::string* value) override;
+ binder::Status setProcSysNet(int32_t ipversion, int32_t which, const std::string& ifname,
+ const std::string& parameter, const std::string& value) override;
// Metrics reporting level set / get (internal use only).
binder::Status getMetricsReportingLevel(int *reportingLevel) override;
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
index 3ed4f8c..5e42770 100644
--- a/server/binder/android/net/INetd.aidl
+++ b/server/binder/android/net/INetd.aidl
@@ -291,20 +291,24 @@
/**
* Set and get /proc/sys/net interface configuration parameters.
*
- * @param family One of IPV4/IPV6 integers, indicating the desired address family directory.
+ * @param ipversion One of IPV4/IPV6 integers, indicating the desired IP version directory.
* @param which One of CONF/NEIGH integers, indicating the desired parameter category directory.
* @param ifname The interface name portion of the path; may also be "all" or "default".
* @param parameter The parameter name portion of the path.
* @param value The value string to be written into the assembled path.
+ *
+ * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
+ * unix errno.
*/
const int IPV4 = 4;
const int IPV6 = 6;
const int CONF = 1;
const int NEIGH = 2;
- void setProcSysNet(int family, int which, in @utf8InCpp String ifname,
+ @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname,
+ in @utf8InCpp String parameter);
+ void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname,
in @utf8InCpp String parameter, in @utf8InCpp String value);
- // TODO: add corresponding getProcSysNet().
/**
* Get/Set metrics reporting level.