Merge "Prohibit address families by default unless a VPN explicitly allows them." into lmp-dev
diff --git a/server/CommandListener.cpp b/server/CommandListener.cpp
index ab6b952..cba3731 100644
--- a/server/CommandListener.cpp
+++ b/server/CommandListener.cpp
@@ -1345,9 +1345,9 @@
return syntaxError(client, "Missing argument");
}
- // 0 1 2 3 4 5 6 7 8
- // network route [legacy <uid>] add <netId> <interface> <destination> [nexthop]
- // network route [legacy <uid>] remove <netId> <interface> <destination> [nexthop]
+ // 0 1 2 3 4 5 6 7 8
+ // network route [legacy <uid>] add <netId> <interface> <destination> [nexthop|"unreachable"]
+ // network route [legacy <uid>] remove <netId> <interface> <destination> [nexthop|"unreachable"]
if (!strcmp(argv[1], "route")) {
if (argc < 6 || argc > 9) {
return syntaxError(client, "Incorrect number of arguments");
@@ -1370,6 +1370,10 @@
}
++nextArg;
+ if (argc < nextArg + 3 || argc > nextArg + 4) {
+ return syntaxError(client, "Incorrect number of arguments");
+ }
+
unsigned netId = stringToNetId(argv[nextArg++]);
const char* interface = argv[nextArg++];
const char* destination = argv[nextArg++];
diff --git a/server/NetworkController.h b/server/NetworkController.h
index 104f98c..fca4125 100644
--- a/server/NetworkController.h
+++ b/server/NetworkController.h
@@ -72,6 +72,9 @@
int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) WARN_UNUSED_RESULT;
+ // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
+ // route that's blocked) or a regular IP address.
+ //
// Routes are added to tables determined by the interface, so only |interface| is actually used.
// |netId| is given only to sanity check that the interface has the correct netId.
int addRoute(unsigned netId, const char* interface, const char* destination,
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 92b4a94..355326d 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -354,27 +354,38 @@
return -ENOBUFS; // Cannot happen; parsePrefix only supports IPv4 and IPv6.
}
- // If an interface was specified, find the ifindex.
+ uint8_t type = RTN_UNICAST;
uint32_t ifindex;
- if (interface != OIF_NONE) {
- ifindex = if_nametoindex(interface);
- if (!ifindex) {
- ALOGE("cannot find interface %s", interface);
- return -ENODEV;
- }
- }
-
- // If a nexthop was specified, parse it as the same family as the prefix.
uint8_t rawNexthop[sizeof(in6_addr)];
- if (nexthop && inet_pton(family, nexthop, rawNexthop) <= 0) {
- ALOGE("inet_pton failed for nexthop %s", nexthop);
- return -EINVAL;
+
+ if (nexthop && !strcmp(nexthop, "unreachable")) {
+ type = RTN_UNREACHABLE;
+ // 'interface' is likely non-NULL, as the caller (modifyRoute()) likely used it to lookup
+ // the table number. But it's an error to specify an interface ("dev ...") or a nexthop for
+ // unreachable routes, so nuke them. (IPv6 allows them to be specified; IPv4 doesn't.)
+ interface = OIF_NONE;
+ nexthop = NULL;
+ } else {
+ // If an interface was specified, find the ifindex.
+ if (interface != OIF_NONE) {
+ ifindex = if_nametoindex(interface);
+ if (!ifindex) {
+ ALOGE("cannot find interface %s", interface);
+ return -ENODEV;
+ }
+ }
+
+ // If a nexthop was specified, parse it as the same family as the prefix.
+ if (nexthop && inet_pton(family, nexthop, rawNexthop) <= 0) {
+ ALOGE("inet_pton failed for nexthop %s", nexthop);
+ return -EINVAL;
+ }
}
// Assemble a rtmsg and put it in an array of iovec structures.
rtmsg route = {
.rtm_protocol = RTPROT_STATIC,
- .rtm_type = RTN_UNICAST,
+ .rtm_type = type,
.rtm_family = family,
.rtm_dst_len = prefixLength,
};
diff --git a/server/RouteController.h b/server/RouteController.h
index 3d00a66..b21bc77 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -66,6 +66,8 @@
static int removeInterfaceFromDefaultNetwork(const char* interface,
Permission permission) WARN_UNUSED_RESULT;
+ // |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
+ // route that's blocked) or a regular IP address.
static int addRoute(const char* interface, const char* destination, const char* nexthop,
TableType tableType) WARN_UNUSED_RESULT;
static int removeRoute(const char* interface, const char* destination, const char* nexthop,