netd: Route MTU
- Route may include optional MTU parameter
- Change route is added so routes don't need to be deleted then re-added
- Add/Del/Change functions to pass route info as parcel
Bug: 142892223
Test: new unit tests
Change-Id: Idc32ecb0520b1f4136b3fe0e3f7b6800fb3005a6
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index 90fd602..66baace 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -1635,26 +1635,52 @@
namespace {
std::string ipRouteString(const std::string& ifName, const std::string& dst,
- const std::string& nextHop) {
+ const std::string& nextHop, const std::string& mtu) {
std::string dstString = (dst == "0.0.0.0/0" || dst == "::/0") ? "default" : dst;
if (!nextHop.empty()) {
dstString += " via " + nextHop;
}
- return dstString + " dev " + ifName;
+ dstString += " dev " + ifName;
+
+ if (!mtu.empty()) {
+ dstString += " proto static";
+ // IPv6 routes report the metric, IPv4 routes report the scope.
+ // TODO: move away from specifying the entire string and use a regexp instead.
+ if (dst.find(':') != std::string::npos) {
+ dstString += " metric 1024";
+ } else {
+ if (nextHop.empty()) {
+ dstString += " scope link";
+ }
+ }
+ dstString += " mtu " + mtu;
+ }
+
+ return dstString;
+}
+
+void expectNetworkRouteExistsWithMtu(const char* ipVersion, const std::string& ifName,
+ const std::string& dst, const std::string& nextHop,
+ const std::string& mtu, const char* table) {
+ std::string routeString = ipRouteString(ifName, dst, nextHop, mtu);
+ EXPECT_TRUE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop, mtu)))
+ << "Couldn't find route to " << dst << ": '" << routeString << "' in table " << table;
}
void expectNetworkRouteExists(const char* ipVersion, const std::string& ifName,
const std::string& dst, const std::string& nextHop,
const char* table) {
- EXPECT_TRUE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop)));
+ expectNetworkRouteExistsWithMtu(ipVersion, ifName, dst, nextHop, "", table);
}
void expectNetworkRouteDoesNotExist(const char* ipVersion, const std::string& ifName,
const std::string& dst, const std::string& nextHop,
const char* table) {
- EXPECT_FALSE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop)));
+ std::string routeString = ipRouteString(ifName, dst, nextHop, "");
+ EXPECT_FALSE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop, "")))
+ << "Found unexpected route " << routeString << " in table " << table;
}
bool ipRuleExists(const char* ipVersion, const std::string& ipRule) {
@@ -1886,6 +1912,46 @@
}
}
+ for (size_t i = 0; i < std::size(kTestData); i++) {
+ const auto& td = kTestData[i];
+ int mtu = (i % 2) ? 1480 : 1280;
+
+ android::net::RouteInfoParcel parcel;
+ parcel.ifName = sTun.name();
+ parcel.destination = td.testDest;
+ parcel.nextHop = td.testNextHop;
+ parcel.mtu = mtu;
+ binder::Status status = mNetd->networkAddRouteParcel(TEST_NETID1, parcel);
+ if (td.expectSuccess) {
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+ } else {
+ EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
+ EXPECT_NE(0, status.serviceSpecificErrorCode());
+ }
+
+ parcel.mtu = 1337;
+ status = mNetd->networkUpdateRouteParcel(TEST_NETID1, parcel);
+ if (td.expectSuccess) {
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+ } else {
+ EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
+ EXPECT_NE(0, status.serviceSpecificErrorCode());
+ }
+
+ status = mNetd->networkRemoveRouteParcel(TEST_NETID1, parcel);
+ if (td.expectSuccess) {
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectNetworkRouteDoesNotExist(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
+ sTun.name().c_str());
+ } else {
+ EXPECT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
+ EXPECT_NE(0, status.serviceSpecificErrorCode());
+ }
+ }
// Remove test physical network
EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}