From 182cd3c8f0f3637288ff07ccd64e77c96afc3a0a Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Sat, 4 Apr 2020 00:44:01 +0900 Subject: Convert tethering offload IPCs from primitive args to a parcel. Defining stable AIDL IPCs with primitive args is not future-proof because AIDL does not support method overloading, so any time a parameter is added a new method needs to be created. It's better to use parcelables for parameters instead, because parcelables can be extended in subsequent version. Define a TetherOffloadRuleParcel data structure to represent tethering offload rules, and switch the tethering offload IPCs to it before we freeze the INetd AIDL. Bug: 140541991 Test: atest netd_integration_test Change-Id: I6e84b14872d38a897eb6a10fd37d816ec7e6da64 --- server/TetherController.cpp | 69 +++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 25 deletions(-) (limited to 'server/TetherController.cpp') diff --git a/server/TetherController.cpp b/server/TetherController.cpp index cc3b49c0..144d24f4 100644 --- a/server/TetherController.cpp +++ b/server/TetherController.cpp @@ -55,6 +55,8 @@ #include "Permission.h" #include "TetherController.h" +#include "android/net/TetherOffloadRuleParcel.h" + namespace android { namespace net { @@ -65,6 +67,7 @@ using android::base::Result; using android::base::StringAppendF; using android::base::StringPrintf; using android::base::unique_fd; +using android::net::TetherOffloadRuleParcel; using android::netdutils::DumpWriter; using android::netdutils::ScopedIndent; using android::netdutils::statusFromErrno; @@ -821,47 +824,63 @@ int TetherController::disableNat(const char* intIface, const char* extIface) { return 0; } -Result TetherController::addDownstreamIpv6Rule(int intIfaceIndex, int extIfaceIndex, - const std::vector& ipAddress, - const std::vector& srcL2Address, - const std::vector& dstL2Address) { - ethhdr hdr = { - .h_proto = htons(ETH_P_IPV6), - }; - if (ipAddress.size() != sizeof(in6_addr)) { - return Error(EINVAL) << "Invalid IP address length " << ipAddress.size(); +namespace { +Result validateOffloadRule(const TetherOffloadRuleParcel& rule) { + struct ethhdr hdr; + + if (rule.inputInterfaceIndex <= 0) { + return Error(ENODEV) << "Invalid input interface " << rule.inputInterfaceIndex; + } + if (rule.outputInterfaceIndex <= 0) { + return Error(ENODEV) << "Invalid output interface " << rule.inputInterfaceIndex; + } + if (rule.prefixLength != 128) { + return Error(EINVAL) << "Prefix length must be 128, not " << rule.prefixLength; + } + if (rule.destination.size() != sizeof(in6_addr)) { + return Error(EAFNOSUPPORT) << "Invalid IP address length " << rule.destination.size(); } - if (srcL2Address.size() != sizeof(hdr.h_source)) { - return Error(EINVAL) << "Invalid L2 src address length " << srcL2Address.size(); + if (rule.srcL2Address.size() != sizeof(hdr.h_source)) { + return Error(ENXIO) << "Invalid L2 src address length " << rule.srcL2Address.size(); } - if (dstL2Address.size() != sizeof(hdr.h_dest)) { - return Error(EINVAL) << "Invalid L2 dst address length " << dstL2Address.size(); + if (rule.dstL2Address.size() != sizeof(hdr.h_dest)) { + return Error(ENXIO) << "Invalid L2 dst address length " << rule.dstL2Address.size(); } - memcpy(&hdr.h_dest, dstL2Address.data(), sizeof(hdr.h_dest)); - memcpy(&hdr.h_source, srcL2Address.data(), sizeof(hdr.h_source)); + return Result(); +} +} // namespace + +Result TetherController::addOffloadRule(const TetherOffloadRuleParcel& rule) { + Result res = validateOffloadRule(rule); + if (!res.ok()) return res; + + ethhdr hdr = { + .h_proto = htons(ETH_P_IPV6), + }; + memcpy(&hdr.h_dest, rule.dstL2Address.data(), sizeof(hdr.h_dest)); + memcpy(&hdr.h_source, rule.srcL2Address.data(), sizeof(hdr.h_source)); + // Only downstream supported for now. TetherIngressKey key = { - .iif = static_cast(extIfaceIndex), - .neigh6 = *(const in6_addr*)ipAddress.data(), + .iif = static_cast(rule.inputInterfaceIndex), + .neigh6 = *(const in6_addr*)rule.destination.data(), }; TetherIngressValue value = { - static_cast(intIfaceIndex), + static_cast(rule.outputInterfaceIndex), hdr, }; return mBpfIngressMap.writeValue(key, value, BPF_ANY); } -Result TetherController::removeDownstreamIpv6Rule(int extIfaceIndex, - const std::vector& ipAddress) { - if (ipAddress.size() != sizeof(in6_addr)) { - return Error(EINVAL) << "Invalid IP address length " << ipAddress.size(); - } +Result TetherController::removeOffloadRule(const TetherOffloadRuleParcel& rule) { + Result res = validateOffloadRule(rule); + if (!res.ok()) return res; TetherIngressKey key = { - .iif = static_cast(extIfaceIndex), - .neigh6 = *(const in6_addr*)ipAddress.data(), + .iif = static_cast(rule.inputInterfaceIndex), + .neigh6 = *(const in6_addr*)rule.destination.data(), }; Result ret = mBpfIngressMap.deleteValue(key); -- cgit v1.2.3