Prohibit address families by default unless a VPN explicitly allows them.
Bug: 15972465
Change-Id: I3278d94536fefacc86390c1ba4231680f7be8589
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index 92aead0..4353174 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,
};