summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2017-09-08 11:31:59 +0900
committerLorenzo Colitti <lorenzo@google.com>2017-09-15 15:58:33 +0900
commit639696d77d19edb8298a21500b9fe1d101ec0b62 (patch)
tree1166edfaa9bec17bd850ed66288df1b85c0aac0f
parent050085a56162dff203979e8c62cb57449f5f7a26 (diff)
downloadnetd-639696d77d19edb8298a21500b9fe1d101ec0b62.tar.gz
Invalidate dst caches when changing network permissions.
Bug: 64103722 Test: builds Test: connected socket UDP traffic switches to wifi when cell goes into background Change-Id: I22e618be40d61be6d5f56a6fc4e5a71e1606c2f8 Merged-In: I22e618be40d61be6d5f56a6fc4e5a71e1606c2f8
-rw-r--r--server/PhysicalNetwork.cpp13
-rw-r--r--server/PhysicalNetwork.h1
-rw-r--r--server/RouteController.cpp13
3 files changed, 27 insertions, 0 deletions
diff --git a/server/PhysicalNetwork.cpp b/server/PhysicalNetwork.cpp
index ccac3233..579d0bdd 100644
--- a/server/PhysicalNetwork.cpp
+++ b/server/PhysicalNetwork.cpp
@@ -86,6 +86,18 @@ int PhysicalNetwork::destroySocketsLackingPermission(Permission permission) {
return 0;
}
+void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
+ for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
+ // If any of these operations fail, there's no point in logging because RouteController will
+ // have already logged a message. There's also no point returning an error since there's
+ // nothing we can do.
+ (void) RouteController::addRoute(interface.c_str(), dst, "throw",
+ RouteController::INTERFACE);
+ (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
+ RouteController::INTERFACE);
+ }
+}
+
int PhysicalNetwork::setPermission(Permission permission) {
if (permission == mPermission) {
return 0;
@@ -103,6 +115,7 @@ int PhysicalNetwork::setPermission(Permission permission) {
interface.c_str(), mNetId, mPermission, permission);
return ret;
}
+ invalidateRouteCache(interface);
}
if (mIsDefault) {
for (const std::string& interface : mInterfaces) {
diff --git a/server/PhysicalNetwork.h b/server/PhysicalNetwork.h
index 9200955f..89c9443b 100644
--- a/server/PhysicalNetwork.h
+++ b/server/PhysicalNetwork.h
@@ -50,6 +50,7 @@ private:
int addInterface(const std::string& interface) override WARN_UNUSED_RESULT;
int removeInterface(const std::string& interface) override WARN_UNUSED_RESULT;
int destroySocketsLackingPermission(Permission permission);
+ void invalidateRouteCache(const std::string& interface);
Delegate* const mDelegate;
Permission mPermission;
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index d7ab7960..376dd9d2 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -81,6 +81,14 @@ const char* const ROUTE_TABLE_NAME_LEGACY_SYSTEM = "legacy_system";
const char* const ROUTE_TABLE_NAME_LOCAL = "local";
const char* const ROUTE_TABLE_NAME_MAIN = "main";
+// None of our routes specify priority, which causes them to have the default
+// priority. For throw routes, we use a fixed priority of 100000. This is
+// because we use throw routes either for maximum-length routes (/32 for IPv4,
+// /128 for IPv6), which we never create with any other priority, or for
+// purposely-low-priority default routes that should never match if there is
+// any other route in the table.
+uint32_t PRIO_THROW = 100000;
+
// These values are upstream, but not yet in our headers.
// TODO: delete these definitions when updating the headers.
const uint16_t FRA_UID_RANGE = 20;
@@ -118,6 +126,7 @@ rtattr FRATTR_UID_RANGE = { U16_RTA_LENGTH(sizeof(fib_rule_uid_range)), FRA_UID_
rtattr RTATTR_TABLE = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_TABLE };
rtattr RTATTR_OIF = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_OIF };
+rtattr RTATTR_PRIO = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_PRIORITY };
uint8_t PADDING_BUFFER[RTA_ALIGNTO] = {0, 0, 0, 0};
@@ -371,6 +380,8 @@ WARN_UNUSED_RESULT int modifyIpRoute(uint16_t action, uint32_t table, const char
}
}
+ bool isDefaultThrowRoute = (type == RTN_THROW && prefixLength == 0);
+
// Assemble a rtmsg and put it in an array of iovec structures.
rtmsg route = {
.rtm_protocol = RTPROT_STATIC,
@@ -394,6 +405,8 @@ WARN_UNUSED_RESULT int modifyIpRoute(uint16_t action, uint32_t table, const char
{ &ifindex, interface != OIF_NONE ? sizeof(ifindex) : 0 },
{ &rtaGateway, nexthop ? sizeof(rtaGateway) : 0 },
{ rawNexthop, nexthop ? static_cast<size_t>(rawLength) : 0 },
+ { &RTATTR_PRIO, isDefaultThrowRoute ? sizeof(RTATTR_PRIO) : 0 },
+ { &PRIO_THROW, isDefaultThrowRoute ? sizeof(PRIO_THROW) : 0 },
};
uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS :