1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "RouteController.h" 18 19#include <arpa/inet.h> 20#include <errno.h> 21#include <fcntl.h> 22#include <linux/fib_rules.h> 23#include <net/if.h> 24#include <sys/stat.h> 25 26#include <private/android_filesystem_config.h> 27 28#include <map> 29 30#include "DummyNetwork.h" 31#include "Fwmark.h" 32#include "NetdConstants.h" 33#include "NetlinkCommands.h" 34#include "UidRanges.h" 35 36#include "android-base/file.h" 37#include <android-base/stringprintf.h> 38#define LOG_TAG "Netd" 39#include "log/log.h" 40#include "logwrap/logwrap.h" 41#include "netutils/ifc.h" 42#include "resolv_netid.h" 43 44using android::base::StringPrintf; 45using android::base::WriteStringToFile; 46using android::net::UidRange; 47 48namespace android { 49namespace net { 50 51auto RouteController::iptablesRestoreCommandFunction = execIptablesRestoreCommand; 52 53// BEGIN CONSTANTS -------------------------------------------------------------------------------- 54 55const uint32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000; 56const uint32_t RULE_PRIORITY_VPN_OVERRIDE_OIF = 10500; 57const uint32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 11000; 58const uint32_t RULE_PRIORITY_SECURE_VPN = 12000; 59const uint32_t RULE_PRIORITY_PROHIBIT_NON_VPN = 12500; 60const uint32_t RULE_PRIORITY_EXPLICIT_NETWORK = 13000; 61const uint32_t RULE_PRIORITY_OUTPUT_INTERFACE = 14000; 62const uint32_t RULE_PRIORITY_LEGACY_SYSTEM = 15000; 63const uint32_t RULE_PRIORITY_LEGACY_NETWORK = 16000; 64const uint32_t RULE_PRIORITY_LOCAL_NETWORK = 17000; 65const uint32_t RULE_PRIORITY_TETHERING = 18000; 66const uint32_t RULE_PRIORITY_IMPLICIT_NETWORK = 19000; 67const uint32_t RULE_PRIORITY_BYPASSABLE_VPN = 20000; 68const uint32_t RULE_PRIORITY_VPN_FALLTHROUGH = 21000; 69const uint32_t RULE_PRIORITY_DEFAULT_NETWORK = 22000; 70const uint32_t RULE_PRIORITY_DIRECTLY_CONNECTED = 23000; 71const uint32_t RULE_PRIORITY_UNREACHABLE = 32000; 72 73const uint32_t ROUTE_TABLE_LOCAL_NETWORK = 97; 74const uint32_t ROUTE_TABLE_LEGACY_NETWORK = 98; 75const uint32_t ROUTE_TABLE_LEGACY_SYSTEM = 99; 76 77const char* const ROUTE_TABLE_NAME_LOCAL_NETWORK = "local_network"; 78const char* const ROUTE_TABLE_NAME_LEGACY_NETWORK = "legacy_network"; 79const char* const ROUTE_TABLE_NAME_LEGACY_SYSTEM = "legacy_system"; 80 81const char* const ROUTE_TABLE_NAME_LOCAL = "local"; 82const char* const ROUTE_TABLE_NAME_MAIN = "main"; 83 84// These values are upstream, but not yet in our headers. 85// TODO: delete these definitions when updating the headers. 86const uint16_t FRA_UID_RANGE = 20; 87struct fib_rule_uid_range { 88 __u32 start; 89 __u32 end; 90}; 91 92const uint8_t AF_FAMILIES[] = {AF_INET, AF_INET6}; 93 94const uid_t UID_ROOT = 0; 95const char* const IIF_LOOPBACK = "lo"; 96const char* const IIF_NONE = NULL; 97const char* const OIF_NONE = NULL; 98const bool ACTION_ADD = true; 99const bool ACTION_DEL = false; 100const bool MODIFY_NON_UID_BASED_RULES = true; 101 102const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables"; 103const mode_t RT_TABLES_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // mode 0644, rw-r--r-- 104 105// Avoids "non-constant-expression cannot be narrowed from type 'unsigned int' to 'unsigned short'" 106// warnings when using RTA_LENGTH(x) inside static initializers (even when x is already uint16_t). 107constexpr uint16_t U16_RTA_LENGTH(uint16_t x) { 108 return RTA_LENGTH(x); 109} 110 111// These are practically const, but can't be declared so, because they are used to initialize 112// non-const pointers ("void* iov_base") in iovec arrays. 113rtattr FRATTR_PRIORITY = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_PRIORITY }; 114rtattr FRATTR_TABLE = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_TABLE }; 115rtattr FRATTR_FWMARK = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_FWMARK }; 116rtattr FRATTR_FWMASK = { U16_RTA_LENGTH(sizeof(uint32_t)), FRA_FWMASK }; 117rtattr FRATTR_UID_RANGE = { U16_RTA_LENGTH(sizeof(fib_rule_uid_range)), FRA_UID_RANGE }; 118 119rtattr RTATTR_TABLE = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_TABLE }; 120rtattr RTATTR_OIF = { U16_RTA_LENGTH(sizeof(uint32_t)), RTA_OIF }; 121 122uint8_t PADDING_BUFFER[RTA_ALIGNTO] = {0, 0, 0, 0}; 123 124// END CONSTANTS ---------------------------------------------------------------------------------- 125 126const char *actionName(uint16_t action) { 127 static const char *ops[4] = {"adding", "deleting", "getting", "???"}; 128 return ops[action % 4]; 129} 130 131const char *familyName(uint8_t family) { 132 switch (family) { 133 case AF_INET: return "IPv4"; 134 case AF_INET6: return "IPv6"; 135 default: return "???"; 136 } 137} 138 139// No locks needed because RouteController is accessed only from one thread (in CommandListener). 140std::map<std::string, uint32_t> interfaceToTable; 141 142uint32_t getRouteTableForInterface(const char* interface) { 143 uint32_t index = if_nametoindex(interface); 144 if (index) { 145 index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX; 146 interfaceToTable[interface] = index; 147 return index; 148 } 149 // If the interface goes away if_nametoindex() will return 0 but we still need to know 150 // the index so we can remove the rules and routes. 151 auto iter = interfaceToTable.find(interface); 152 if (iter == interfaceToTable.end()) { 153 ALOGE("cannot find interface %s", interface); 154 return RT_TABLE_UNSPEC; 155 } 156 return iter->second; 157} 158 159void addTableName(uint32_t table, const std::string& name, std::string* contents) { 160 char tableString[UINT32_STRLEN]; 161 snprintf(tableString, sizeof(tableString), "%u", table); 162 *contents += tableString; 163 *contents += " "; 164 *contents += name; 165 *contents += "\n"; 166} 167 168// Doesn't return success/failure as the file is optional; it's okay if we fail to update it. 169void updateTableNamesFile() { 170 std::string contents; 171 172 addTableName(RT_TABLE_LOCAL, ROUTE_TABLE_NAME_LOCAL, &contents); 173 addTableName(RT_TABLE_MAIN, ROUTE_TABLE_NAME_MAIN, &contents); 174 175 addTableName(ROUTE_TABLE_LOCAL_NETWORK, ROUTE_TABLE_NAME_LOCAL_NETWORK, &contents); 176 addTableName(ROUTE_TABLE_LEGACY_NETWORK, ROUTE_TABLE_NAME_LEGACY_NETWORK, &contents); 177 addTableName(ROUTE_TABLE_LEGACY_SYSTEM, ROUTE_TABLE_NAME_LEGACY_SYSTEM, &contents); 178 179 for (const auto& entry : interfaceToTable) { 180 addTableName(entry.second, entry.first, &contents); 181 } 182 183 if (!WriteStringToFile(contents, RT_TABLES_PATH, RT_TABLES_MODE, AID_SYSTEM, AID_WIFI)) { 184 ALOGE("failed to write to %s (%s)", RT_TABLES_PATH, strerror(errno)); 185 return; 186 } 187} 188 189// Returns 0 on success or negative errno on failure. 190int padInterfaceName(const char* input, char* name, size_t* length, uint16_t* padding) { 191 if (!input) { 192 *length = 0; 193 *padding = 0; 194 return 0; 195 } 196 *length = strlcpy(name, input, IFNAMSIZ) + 1; 197 if (*length > IFNAMSIZ) { 198 ALOGE("interface name too long (%zu > %u)", *length, IFNAMSIZ); 199 return -ENAMETOOLONG; 200 } 201 *padding = RTA_SPACE(*length) - RTA_LENGTH(*length); 202 return 0; 203} 204 205// Adds or removes a routing rule for IPv4 and IPv6. 206// 207// + If |table| is non-zero, the rule points at the specified routing table. Otherwise, the table is 208// unspecified. An unspecified table is not allowed when creating an FR_ACT_TO_TBL rule. 209// + If |mask| is non-zero, the rule matches the specified fwmark and mask. Otherwise, |fwmark| is 210// ignored. 211// + If |iif| is non-NULL, the rule matches the specified incoming interface. 212// + If |oif| is non-NULL, the rule matches the specified outgoing interface. 213// + If |uidStart| and |uidEnd| are not INVALID_UID, the rule matches packets from UIDs in that 214// range (inclusive). Otherwise, the rule matches packets from all UIDs. 215// 216// Returns 0 on success or negative errno on failure. 217WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint8_t ruleType, 218 uint32_t table, uint32_t fwmark, uint32_t mask, const char* iif, 219 const char* oif, uid_t uidStart, uid_t uidEnd) { 220 // Ensure that if you set a bit in the fwmark, it's not being ignored by the mask. 221 if (fwmark & ~mask) { 222 ALOGE("mask 0x%x does not select all the bits set in fwmark 0x%x", mask, fwmark); 223 return -ERANGE; 224 } 225 226 // Interface names must include exactly one terminating NULL and be properly padded, or older 227 // kernels will refuse to delete rules. 228 char iifName[IFNAMSIZ], oifName[IFNAMSIZ]; 229 size_t iifLength, oifLength; 230 uint16_t iifPadding, oifPadding; 231 if (int ret = padInterfaceName(iif, iifName, &iifLength, &iifPadding)) { 232 return ret; 233 } 234 if (int ret = padInterfaceName(oif, oifName, &oifLength, &oifPadding)) { 235 return ret; 236 } 237 238 // Either both start and end UID must be specified, or neither. 239 if ((uidStart == INVALID_UID) != (uidEnd == INVALID_UID)) { 240 ALOGE("incompatible start and end UIDs (%u vs %u)", uidStart, uidEnd); 241 return -EUSERS; 242 } 243 244 bool isUidRule = (uidStart != INVALID_UID); 245 246 // Assemble a rule request and put it in an array of iovec structures. 247 fib_rule_hdr rule = { 248 .action = ruleType, 249 // Note that here we're implicitly setting rule.table to 0. When we want to specify a 250 // non-zero table, we do this via the FRATTR_TABLE attribute. 251 }; 252 253 // Don't ever create a rule that looks up table 0, because table 0 is the local table. 254 // It's OK to specify a table ID of 0 when deleting a rule, because that doesn't actually select 255 // table 0, it's a wildcard that matches anything. 256 if (table == RT_TABLE_UNSPEC && rule.action == FR_ACT_TO_TBL && action != RTM_DELRULE) { 257 ALOGE("RT_TABLE_UNSPEC only allowed when deleting rules"); 258 return -ENOTUNIQ; 259 } 260 261 rtattr fraIifName = { U16_RTA_LENGTH(iifLength), FRA_IIFNAME }; 262 rtattr fraOifName = { U16_RTA_LENGTH(oifLength), FRA_OIFNAME }; 263 struct fib_rule_uid_range uidRange = { uidStart, uidEnd }; 264 265 iovec iov[] = { 266 { NULL, 0 }, 267 { &rule, sizeof(rule) }, 268 { &FRATTR_PRIORITY, sizeof(FRATTR_PRIORITY) }, 269 { &priority, sizeof(priority) }, 270 { &FRATTR_TABLE, table != RT_TABLE_UNSPEC ? sizeof(FRATTR_TABLE) : 0 }, 271 { &table, table != RT_TABLE_UNSPEC ? sizeof(table) : 0 }, 272 { &FRATTR_FWMARK, mask ? sizeof(FRATTR_FWMARK) : 0 }, 273 { &fwmark, mask ? sizeof(fwmark) : 0 }, 274 { &FRATTR_FWMASK, mask ? sizeof(FRATTR_FWMASK) : 0 }, 275 { &mask, mask ? sizeof(mask) : 0 }, 276 { &FRATTR_UID_RANGE, isUidRule ? sizeof(FRATTR_UID_RANGE) : 0 }, 277 { &uidRange, isUidRule ? sizeof(uidRange) : 0 }, 278 { &fraIifName, iif != IIF_NONE ? sizeof(fraIifName) : 0 }, 279 { iifName, iifLength }, 280 { PADDING_BUFFER, iifPadding }, 281 { &fraOifName, oif != OIF_NONE ? sizeof(fraOifName) : 0 }, 282 { oifName, oifLength }, 283 { PADDING_BUFFER, oifPadding }, 284 }; 285 286 uint16_t flags = (action == RTM_NEWRULE) ? NETLINK_CREATE_REQUEST_FLAGS : NETLINK_REQUEST_FLAGS; 287 for (size_t i = 0; i < ARRAY_SIZE(AF_FAMILIES); ++i) { 288 rule.family = AF_FAMILIES[i]; 289 if (int ret = sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov), nullptr)) { 290 if (!(action == RTM_DELRULE && ret == -ENOENT && priority == RULE_PRIORITY_TETHERING)) { 291 // Don't log when deleting a tethering rule that's not there. This matches the 292 // behaviour of clearTetheringRules, which ignores ENOENT in this case. 293 ALOGE("Error %s %s rule: %s", actionName(action), familyName(rule.family), 294 strerror(-ret)); 295 } 296 return ret; 297 } 298 } 299 300 return 0; 301} 302 303WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table, 304 uint32_t fwmark, uint32_t mask, const char* iif, 305 const char* oif, uid_t uidStart, uid_t uidEnd) { 306 return modifyIpRule(action, priority, FR_ACT_TO_TBL, table, fwmark, mask, iif, oif, uidStart, 307 uidEnd); 308} 309 310WARN_UNUSED_RESULT int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table, 311 uint32_t fwmark, uint32_t mask) { 312 return modifyIpRule(action, priority, table, fwmark, mask, IIF_NONE, OIF_NONE, INVALID_UID, 313 INVALID_UID); 314} 315 316// Adds or deletes an IPv4 or IPv6 route. 317// Returns 0 on success or negative errno on failure. 318WARN_UNUSED_RESULT int modifyIpRoute(uint16_t action, uint32_t table, const char* interface, 319 const char* destination, const char* nexthop) { 320 // At least the destination must be non-null. 321 if (!destination) { 322 ALOGE("null destination"); 323 return -EFAULT; 324 } 325 326 // Parse the prefix. 327 uint8_t rawAddress[sizeof(in6_addr)]; 328 uint8_t family; 329 uint8_t prefixLength; 330 int rawLength = parsePrefix(destination, &family, rawAddress, sizeof(rawAddress), 331 &prefixLength); 332 if (rawLength < 0) { 333 ALOGE("parsePrefix failed for destination %s (%s)", destination, strerror(-rawLength)); 334 return rawLength; 335 } 336 337 if (static_cast<size_t>(rawLength) > sizeof(rawAddress)) { 338 ALOGE("impossible! address too long (%d vs %zu)", rawLength, sizeof(rawAddress)); 339 return -ENOBUFS; // Cannot happen; parsePrefix only supports IPv4 and IPv6. 340 } 341 342 uint8_t type = RTN_UNICAST; 343 uint32_t ifindex; 344 uint8_t rawNexthop[sizeof(in6_addr)]; 345 346 if (nexthop && !strcmp(nexthop, "unreachable")) { 347 type = RTN_UNREACHABLE; 348 // 'interface' is likely non-NULL, as the caller (modifyRoute()) likely used it to lookup 349 // the table number. But it's an error to specify an interface ("dev ...") or a nexthop for 350 // unreachable routes, so nuke them. (IPv6 allows them to be specified; IPv4 doesn't.) 351 interface = OIF_NONE; 352 nexthop = NULL; 353 } else if (nexthop && !strcmp(nexthop, "throw")) { 354 type = RTN_THROW; 355 interface = OIF_NONE; 356 nexthop = NULL; 357 } else { 358 // If an interface was specified, find the ifindex. 359 if (interface != OIF_NONE) { 360 ifindex = if_nametoindex(interface); 361 if (!ifindex) { 362 ALOGE("cannot find interface %s", interface); 363 return -ENODEV; 364 } 365 } 366 367 // If a nexthop was specified, parse it as the same family as the prefix. 368 if (nexthop && inet_pton(family, nexthop, rawNexthop) <= 0) { 369 ALOGE("inet_pton failed for nexthop %s", nexthop); 370 return -EINVAL; 371 } 372 } 373 374 // Assemble a rtmsg and put it in an array of iovec structures. 375 rtmsg route = { 376 .rtm_protocol = RTPROT_STATIC, 377 .rtm_type = type, 378 .rtm_family = family, 379 .rtm_dst_len = prefixLength, 380 .rtm_scope = static_cast<uint8_t>(nexthop ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK), 381 }; 382 383 rtattr rtaDst = { U16_RTA_LENGTH(rawLength), RTA_DST }; 384 rtattr rtaGateway = { U16_RTA_LENGTH(rawLength), RTA_GATEWAY }; 385 386 iovec iov[] = { 387 { NULL, 0 }, 388 { &route, sizeof(route) }, 389 { &RTATTR_TABLE, sizeof(RTATTR_TABLE) }, 390 { &table, sizeof(table) }, 391 { &rtaDst, sizeof(rtaDst) }, 392 { rawAddress, static_cast<size_t>(rawLength) }, 393 { &RTATTR_OIF, interface != OIF_NONE ? sizeof(RTATTR_OIF) : 0 }, 394 { &ifindex, interface != OIF_NONE ? sizeof(ifindex) : 0 }, 395 { &rtaGateway, nexthop ? sizeof(rtaGateway) : 0 }, 396 { rawNexthop, nexthop ? static_cast<size_t>(rawLength) : 0 }, 397 }; 398 399 uint16_t flags = (action == RTM_NEWROUTE) ? NETLINK_CREATE_REQUEST_FLAGS : 400 NETLINK_REQUEST_FLAGS; 401 int ret = sendNetlinkRequest(action, flags, iov, ARRAY_SIZE(iov), nullptr); 402 if (ret) { 403 ALOGE("Error %s route %s -> %s %s to table %u: %s", 404 actionName(action), destination, nexthop, interface, table, strerror(-ret)); 405 } 406 return ret; 407} 408 409// An iptables rule to mark incoming packets on a network with the netId of the network. 410// 411// This is so that the kernel can: 412// + Use the right fwmark for (and thus correctly route) replies (e.g.: TCP RST, ICMP errors, ping 413// replies, SYN-ACKs, etc). 414// + Mark sockets that accept connections from this interface so that the connection stays on the 415// same interface. 416WARN_UNUSED_RESULT int modifyIncomingPacketMark(unsigned netId, const char* interface, 417 Permission permission, bool add) { 418 Fwmark fwmark; 419 420 fwmark.netId = netId; 421 fwmark.explicitlySelected = true; 422 fwmark.protectedFromVpn = true; 423 fwmark.permission = permission; 424 425 std::string cmd = StringPrintf("%s INPUT -i %s -j MARK --set-mark 0x%x", 426 add ? "-A" : "-D", interface, fwmark.intValue); 427 if (RouteController::iptablesRestoreCommandFunction(V4V6, "mangle", cmd, nullptr) != 0) { 428 ALOGE("failed to change iptables rule that sets incoming packet mark"); 429 return -EREMOTEIO; 430 } 431 432 return 0; 433} 434 435// A rule to route responses to the local network forwarded via the VPN. 436// 437// When a VPN is in effect, packets from the local network to upstream networks are forwarded into 438// the VPN's tunnel interface. When the VPN forwards the responses, they emerge out of the tunnel. 439WARN_UNUSED_RESULT int modifyVpnOutputToLocalRule(const char* vpnInterface, bool add) { 440 return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL, 441 ROUTE_TABLE_LOCAL_NETWORK, MARK_UNSET, MARK_UNSET, vpnInterface, OIF_NONE, 442 INVALID_UID, INVALID_UID); 443} 444 445// A rule to route all traffic from a given set of UIDs to go over the VPN. 446// 447// Notice that this rule doesn't use the netId. I.e., no matter what netId the user's socket may 448// have, if they are subject to this VPN, their traffic has to go through it. Allows the traffic to 449// bypass the VPN if the protectedFromVpn bit is set. 450WARN_UNUSED_RESULT int modifyVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd, 451 bool secure, bool add) { 452 Fwmark fwmark; 453 Fwmark mask; 454 455 fwmark.protectedFromVpn = false; 456 mask.protectedFromVpn = true; 457 458 uint32_t priority; 459 460 if (secure) { 461 priority = RULE_PRIORITY_SECURE_VPN; 462 } else { 463 priority = RULE_PRIORITY_BYPASSABLE_VPN; 464 465 fwmark.explicitlySelected = false; 466 mask.explicitlySelected = true; 467 } 468 469 return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue, 470 mask.intValue, IIF_LOOPBACK, OIF_NONE, uidStart, uidEnd); 471} 472 473// A rule to allow system apps to send traffic over this VPN even if they are not part of the target 474// set of UIDs. 475// 476// This is needed for DnsProxyListener to correctly resolve a request for a user who is in the 477// target set, but where the DnsProxyListener itself is not. 478WARN_UNUSED_RESULT int modifyVpnSystemPermissionRule(unsigned netId, uint32_t table, bool secure, 479 bool add) { 480 Fwmark fwmark; 481 Fwmark mask; 482 483 fwmark.netId = netId; 484 mask.netId = FWMARK_NET_ID_MASK; 485 486 fwmark.permission = PERMISSION_SYSTEM; 487 mask.permission = PERMISSION_SYSTEM; 488 489 uint32_t priority = secure ? RULE_PRIORITY_SECURE_VPN : RULE_PRIORITY_BYPASSABLE_VPN; 490 491 return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue, 492 mask.intValue); 493} 494 495// A rule to route traffic based on an explicitly chosen network. 496// 497// Supports apps that use the multinetwork APIs to restrict their traffic to a network. 498// 499// Even though we check permissions at the time we set a netId into the fwmark of a socket, we need 500// to check it again in the rules here, because a network's permissions may have been updated via 501// modifyNetworkPermission(). 502WARN_UNUSED_RESULT int modifyExplicitNetworkRule(unsigned netId, uint32_t table, 503 Permission permission, uid_t uidStart, 504 uid_t uidEnd, bool add) { 505 Fwmark fwmark; 506 Fwmark mask; 507 508 fwmark.netId = netId; 509 mask.netId = FWMARK_NET_ID_MASK; 510 511 fwmark.explicitlySelected = true; 512 mask.explicitlySelected = true; 513 514 fwmark.permission = permission; 515 mask.permission = permission; 516 517 return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_EXPLICIT_NETWORK, table, 518 fwmark.intValue, mask.intValue, IIF_NONE, OIF_NONE, uidStart, uidEnd); 519} 520 521// A rule to route traffic based on a chosen outgoing interface. 522// 523// Supports apps that use SO_BINDTODEVICE or IP_PKTINFO options and the kernel that already knows 524// the outgoing interface (typically for link-local communications). 525WARN_UNUSED_RESULT int modifyOutputInterfaceRules(const char* interface, uint32_t table, 526 Permission permission, uid_t uidStart, 527 uid_t uidEnd, bool add) { 528 Fwmark fwmark; 529 Fwmark mask; 530 531 fwmark.permission = permission; 532 mask.permission = permission; 533 534 // If this rule does not specify a UID range, then also add a corresponding high-priority rule 535 // for UID. This covers forwarded packets and system daemons such as the tethering DHCP server. 536 if (uidStart == INVALID_UID && uidEnd == INVALID_UID) { 537 if (int ret = modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_VPN_OVERRIDE_OIF, 538 table, fwmark.intValue, mask.intValue, IIF_NONE, interface, 539 UID_ROOT, UID_ROOT)) { 540 return ret; 541 } 542 } 543 544 return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_OUTPUT_INTERFACE, table, 545 fwmark.intValue, mask.intValue, IIF_NONE, interface, uidStart, uidEnd); 546} 547 548// A rule to route traffic based on the chosen network. 549// 550// This is for sockets that have not explicitly requested a particular network, but have been 551// bound to one when they called connect(). This ensures that sockets connected on a particular 552// network stay on that network even if the default network changes. 553WARN_UNUSED_RESULT int modifyImplicitNetworkRule(unsigned netId, uint32_t table, 554 Permission permission, bool add) { 555 Fwmark fwmark; 556 Fwmark mask; 557 558 fwmark.netId = netId; 559 mask.netId = FWMARK_NET_ID_MASK; 560 561 fwmark.explicitlySelected = false; 562 mask.explicitlySelected = true; 563 564 fwmark.permission = permission; 565 mask.permission = permission; 566 567 return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_IMPLICIT_NETWORK, table, 568 fwmark.intValue, mask.intValue); 569} 570 571// A rule to enable split tunnel VPNs. 572// 573// If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to 574// go over the default network, provided it wasn't explicitly restricted to the VPN and has the 575// permissions required by the default network. 576WARN_UNUSED_RESULT int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId, 577 const char* physicalInterface, 578 Permission permission) { 579 uint32_t table = getRouteTableForInterface(physicalInterface); 580 if (table == RT_TABLE_UNSPEC) { 581 return -ESRCH; 582 } 583 584 Fwmark fwmark; 585 Fwmark mask; 586 587 fwmark.netId = vpnNetId; 588 mask.netId = FWMARK_NET_ID_MASK; 589 590 fwmark.explicitlySelected = false; 591 mask.explicitlySelected = true; 592 593 fwmark.permission = permission; 594 mask.permission = permission; 595 596 return modifyIpRule(action, RULE_PRIORITY_VPN_FALLTHROUGH, table, fwmark.intValue, 597 mask.intValue); 598} 599 600// Add rules to allow legacy routes added through the requestRouteToHost() API. 601WARN_UNUSED_RESULT int addLegacyRouteRules() { 602 Fwmark fwmark; 603 Fwmark mask; 604 605 fwmark.explicitlySelected = false; 606 mask.explicitlySelected = true; 607 608 // Rules to allow legacy routes to override the default network. 609 if (int ret = modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_LEGACY_SYSTEM, ROUTE_TABLE_LEGACY_SYSTEM, 610 fwmark.intValue, mask.intValue)) { 611 return ret; 612 } 613 if (int ret = modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_LEGACY_NETWORK, 614 ROUTE_TABLE_LEGACY_NETWORK, fwmark.intValue, mask.intValue)) { 615 return ret; 616 } 617 618 fwmark.permission = PERMISSION_SYSTEM; 619 mask.permission = PERMISSION_SYSTEM; 620 621 // A rule to allow legacy routes from system apps to override VPNs. 622 return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_VPN_OVERRIDE_SYSTEM, ROUTE_TABLE_LEGACY_SYSTEM, 623 fwmark.intValue, mask.intValue); 624} 625 626// Add rules to lookup the local network when specified explicitly or otherwise. 627WARN_UNUSED_RESULT int addLocalNetworkRules(unsigned localNetId) { 628 if (int ret = modifyExplicitNetworkRule(localNetId, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE, 629 INVALID_UID, INVALID_UID, ACTION_ADD)) { 630 return ret; 631 } 632 633 Fwmark fwmark; 634 Fwmark mask; 635 636 fwmark.explicitlySelected = false; 637 mask.explicitlySelected = true; 638 639 return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_LOCAL_NETWORK, ROUTE_TABLE_LOCAL_NETWORK, 640 fwmark.intValue, mask.intValue); 641} 642 643int configureDummyNetwork() { 644 const char *interface = DummyNetwork::INTERFACE_NAME; 645 uint32_t table = getRouteTableForInterface(interface); 646 if (table == RT_TABLE_UNSPEC) { 647 // getRouteTableForInterface has already looged an error. 648 return -ESRCH; 649 } 650 651 ifc_init(); 652 int ret = ifc_up(interface); 653 ifc_close(); 654 if (ret) { 655 ALOGE("Can't bring up %s: %s", interface, strerror(errno)); 656 return -errno; 657 } 658 659 if ((ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, 660 INVALID_UID, INVALID_UID, ACTION_ADD))) { 661 ALOGE("Can't create oif rules for %s: %s", interface, strerror(-ret)); 662 return ret; 663 } 664 665 if ((ret = modifyIpRoute(RTM_NEWROUTE, table, interface, "0.0.0.0/0", NULL))) { 666 return ret; 667 } 668 669 if ((ret = modifyIpRoute(RTM_NEWROUTE, table, interface, "::/0", NULL))) { 670 return ret; 671 } 672 673 return 0; 674} 675 676// Add a new rule to look up the 'main' table, with the same selectors as the "default network" 677// rule, but with a lower priority. We will never create routes in the main table; it should only be 678// used for directly-connected routes implicitly created by the kernel when adding IP addresses. 679// This is necessary, for example, when adding a route through a directly-connected gateway: in 680// order to add the route, there must already be a directly-connected route that covers the gateway. 681WARN_UNUSED_RESULT int addDirectlyConnectedRule() { 682 Fwmark fwmark; 683 Fwmark mask; 684 685 fwmark.netId = NETID_UNSET; 686 mask.netId = FWMARK_NET_ID_MASK; 687 688 return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_DIRECTLY_CONNECTED, RT_TABLE_MAIN, 689 fwmark.intValue, mask.intValue, IIF_NONE, OIF_NONE, UID_ROOT, UID_ROOT); 690} 691 692// Add an explicit unreachable rule close to the end of the prioriy list to make it clear that 693// relying on the kernel-default "from all lookup main" rule at priority 32766 is not intended 694// behaviour. We do flush the kernel-default rules at startup, but having an explicit unreachable 695// rule will hopefully make things even clearer. 696WARN_UNUSED_RESULT int addUnreachableRule() { 697 return modifyIpRule(RTM_NEWRULE, RULE_PRIORITY_UNREACHABLE, FR_ACT_UNREACHABLE, RT_TABLE_UNSPEC, 698 MARK_UNSET, MARK_UNSET, IIF_NONE, OIF_NONE, INVALID_UID, INVALID_UID); 699} 700 701WARN_UNUSED_RESULT int modifyLocalNetwork(unsigned netId, const char* interface, bool add) { 702 if (int ret = modifyIncomingPacketMark(netId, interface, PERMISSION_NONE, add)) { 703 return ret; 704 } 705 return modifyOutputInterfaceRules(interface, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE, 706 INVALID_UID, INVALID_UID, add); 707} 708 709WARN_UNUSED_RESULT int modifyPhysicalNetwork(unsigned netId, const char* interface, 710 Permission permission, bool add) { 711 uint32_t table = getRouteTableForInterface(interface); 712 if (table == RT_TABLE_UNSPEC) { 713 return -ESRCH; 714 } 715 716 if (int ret = modifyIncomingPacketMark(netId, interface, permission, add)) { 717 return ret; 718 } 719 if (int ret = modifyExplicitNetworkRule(netId, table, permission, INVALID_UID, INVALID_UID, 720 add)) { 721 return ret; 722 } 723 if (int ret = modifyOutputInterfaceRules(interface, table, permission, INVALID_UID, INVALID_UID, 724 add)) { 725 return ret; 726 } 727 return modifyImplicitNetworkRule(netId, table, permission, add); 728} 729 730WARN_UNUSED_RESULT int modifyRejectNonSecureNetworkRule(const UidRanges& uidRanges, bool add) { 731 Fwmark fwmark; 732 Fwmark mask; 733 fwmark.protectedFromVpn = false; 734 mask.protectedFromVpn = true; 735 736 for (const UidRange& range : uidRanges.getRanges()) { 737 if (int ret = modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, 738 RULE_PRIORITY_PROHIBIT_NON_VPN, FR_ACT_PROHIBIT, RT_TABLE_UNSPEC, 739 fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, 740 range.getStart(), range.getStop())) { 741 return ret; 742 } 743 } 744 745 return 0; 746} 747 748WARN_UNUSED_RESULT int modifyVirtualNetwork(unsigned netId, const char* interface, 749 const UidRanges& uidRanges, bool secure, bool add, 750 bool modifyNonUidBasedRules) { 751 uint32_t table = getRouteTableForInterface(interface); 752 if (table == RT_TABLE_UNSPEC) { 753 return -ESRCH; 754 } 755 756 for (const UidRange& range : uidRanges.getRanges()) { 757 if (int ret = modifyVpnUidRangeRule(table, range.getStart(), range.getStop(), secure, add)) 758 { 759 return ret; 760 } 761 if (int ret = modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, range.getStart(), 762 range.getStop(), add)) { 763 return ret; 764 } 765 if (int ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, 766 range.getStart(), range.getStop(), add)) { 767 return ret; 768 } 769 } 770 771 if (modifyNonUidBasedRules) { 772 if (int ret = modifyIncomingPacketMark(netId, interface, PERMISSION_NONE, add)) { 773 return ret; 774 } 775 if (int ret = modifyVpnOutputToLocalRule(interface, add)) { 776 return ret; 777 } 778 if (int ret = modifyVpnSystemPermissionRule(netId, table, secure, add)) { 779 return ret; 780 } 781 return modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT, add); 782 } 783 784 return 0; 785} 786 787WARN_UNUSED_RESULT int modifyDefaultNetwork(uint16_t action, const char* interface, 788 Permission permission) { 789 uint32_t table = getRouteTableForInterface(interface); 790 if (table == RT_TABLE_UNSPEC) { 791 return -ESRCH; 792 } 793 794 Fwmark fwmark; 795 Fwmark mask; 796 797 fwmark.netId = NETID_UNSET; 798 mask.netId = FWMARK_NET_ID_MASK; 799 800 fwmark.permission = permission; 801 mask.permission = permission; 802 803 return modifyIpRule(action, RULE_PRIORITY_DEFAULT_NETWORK, table, fwmark.intValue, 804 mask.intValue); 805} 806 807WARN_UNUSED_RESULT int modifyTetheredNetwork(uint16_t action, const char* inputInterface, 808 const char* outputInterface) { 809 uint32_t table = getRouteTableForInterface(outputInterface); 810 if (table == RT_TABLE_UNSPEC) { 811 return -ESRCH; 812 } 813 814 return modifyIpRule(action, RULE_PRIORITY_TETHERING, table, MARK_UNSET, MARK_UNSET, 815 inputInterface, OIF_NONE, INVALID_UID, INVALID_UID); 816} 817 818// Adds or removes an IPv4 or IPv6 route to the specified table and, if it's a directly-connected 819// route, to the main table as well. 820// Returns 0 on success or negative errno on failure. 821WARN_UNUSED_RESULT int modifyRoute(uint16_t action, const char* interface, const char* destination, 822 const char* nexthop, RouteController::TableType tableType) { 823 uint32_t table; 824 switch (tableType) { 825 case RouteController::INTERFACE: { 826 table = getRouteTableForInterface(interface); 827 if (table == RT_TABLE_UNSPEC) { 828 return -ESRCH; 829 } 830 break; 831 } 832 case RouteController::LOCAL_NETWORK: { 833 table = ROUTE_TABLE_LOCAL_NETWORK; 834 break; 835 } 836 case RouteController::LEGACY_NETWORK: { 837 table = ROUTE_TABLE_LEGACY_NETWORK; 838 break; 839 } 840 case RouteController::LEGACY_SYSTEM: { 841 table = ROUTE_TABLE_LEGACY_SYSTEM; 842 break; 843 } 844 } 845 846 int ret = modifyIpRoute(action, table, interface, destination, nexthop); 847 // Trying to add a route that already exists shouldn't cause an error. 848 if (ret && !(action == RTM_NEWROUTE && ret == -EEXIST)) { 849 return ret; 850 } 851 852 return 0; 853} 854 855WARN_UNUSED_RESULT int clearTetheringRules(const char* inputInterface) { 856 int ret = 0; 857 while (ret == 0) { 858 ret = modifyIpRule(RTM_DELRULE, RULE_PRIORITY_TETHERING, 0, MARK_UNSET, MARK_UNSET, 859 inputInterface, OIF_NONE, INVALID_UID, INVALID_UID); 860 } 861 862 if (ret == -ENOENT) { 863 return 0; 864 } else { 865 return ret; 866 } 867} 868 869uint32_t getRulePriority(const nlmsghdr *nlh) { 870 return getRtmU32Attribute(nlh, FRA_PRIORITY); 871} 872 873uint32_t getRouteTable(const nlmsghdr *nlh) { 874 return getRtmU32Attribute(nlh, RTA_TABLE); 875} 876 877WARN_UNUSED_RESULT int flushRules() { 878 NetlinkDumpFilter shouldDelete = [] (nlmsghdr *nlh) { 879 // Don't touch rules at priority 0 because by default they are used for local input. 880 return getRulePriority(nlh) != 0; 881 }; 882 return rtNetlinkFlush(RTM_GETRULE, RTM_DELRULE, "rules", shouldDelete); 883} 884 885WARN_UNUSED_RESULT int flushRoutes(uint32_t table) { 886 NetlinkDumpFilter shouldDelete = [table] (nlmsghdr *nlh) { 887 return getRouteTable(nlh) == table; 888 }; 889 890 return rtNetlinkFlush(RTM_GETROUTE, RTM_DELROUTE, "routes", shouldDelete); 891} 892 893// Returns 0 on success or negative errno on failure. 894WARN_UNUSED_RESULT int flushRoutes(const char* interface) { 895 uint32_t table = getRouteTableForInterface(interface); 896 if (table == RT_TABLE_UNSPEC) { 897 return -ESRCH; 898 } 899 900 int ret = flushRoutes(table); 901 902 // If we failed to flush routes, the caller may elect to keep this interface around, so keep 903 // track of its name. 904 if (ret == 0) { 905 interfaceToTable.erase(interface); 906 } 907 908 return ret; 909} 910 911int RouteController::Init(unsigned localNetId) { 912 if (int ret = flushRules()) { 913 return ret; 914 } 915 if (int ret = addLegacyRouteRules()) { 916 return ret; 917 } 918 if (int ret = addLocalNetworkRules(localNetId)) { 919 return ret; 920 } 921 if (int ret = addDirectlyConnectedRule()) { 922 return ret; 923 } 924 if (int ret = addUnreachableRule()) { 925 return ret; 926 } 927 // Don't complain if we can't add the dummy network, since not all devices support it. 928 configureDummyNetwork(); 929 930 updateTableNamesFile(); 931 return 0; 932} 933 934int RouteController::addInterfaceToLocalNetwork(unsigned netId, const char* interface) { 935 return modifyLocalNetwork(netId, interface, ACTION_ADD); 936} 937 938int RouteController::removeInterfaceFromLocalNetwork(unsigned netId, const char* interface) { 939 return modifyLocalNetwork(netId, interface, ACTION_DEL); 940} 941 942int RouteController::addInterfaceToPhysicalNetwork(unsigned netId, const char* interface, 943 Permission permission) { 944 if (int ret = modifyPhysicalNetwork(netId, interface, permission, ACTION_ADD)) { 945 return ret; 946 } 947 updateTableNamesFile(); 948 return 0; 949} 950 951int RouteController::removeInterfaceFromPhysicalNetwork(unsigned netId, const char* interface, 952 Permission permission) { 953 if (int ret = modifyPhysicalNetwork(netId, interface, permission, ACTION_DEL)) { 954 return ret; 955 } 956 if (int ret = flushRoutes(interface)) { 957 return ret; 958 } 959 if (int ret = clearTetheringRules(interface)) { 960 return ret; 961 } 962 updateTableNamesFile(); 963 return 0; 964} 965 966int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* interface, 967 bool secure, const UidRanges& uidRanges) { 968 if (int ret = modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_ADD, 969 MODIFY_NON_UID_BASED_RULES)) { 970 return ret; 971 } 972 updateTableNamesFile(); 973 return 0; 974} 975 976int RouteController::removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface, 977 bool secure, const UidRanges& uidRanges) { 978 if (int ret = modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_DEL, 979 MODIFY_NON_UID_BASED_RULES)) { 980 return ret; 981 } 982 if (int ret = flushRoutes(interface)) { 983 return ret; 984 } 985 updateTableNamesFile(); 986 return 0; 987} 988 989int RouteController::modifyPhysicalNetworkPermission(unsigned netId, const char* interface, 990 Permission oldPermission, 991 Permission newPermission) { 992 // Add the new rules before deleting the old ones, to avoid race conditions. 993 if (int ret = modifyPhysicalNetwork(netId, interface, newPermission, ACTION_ADD)) { 994 return ret; 995 } 996 return modifyPhysicalNetwork(netId, interface, oldPermission, ACTION_DEL); 997} 998 999int RouteController::addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges) { 1000 return modifyRejectNonSecureNetworkRule(uidRanges, true); 1001} 1002 1003int RouteController::removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges) { 1004 return modifyRejectNonSecureNetworkRule(uidRanges, false); 1005} 1006 1007int RouteController::addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure, 1008 const UidRanges& uidRanges) { 1009 return modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_ADD, 1010 !MODIFY_NON_UID_BASED_RULES); 1011} 1012 1013int RouteController::removeUsersFromVirtualNetwork(unsigned netId, const char* interface, 1014 bool secure, const UidRanges& uidRanges) { 1015 return modifyVirtualNetwork(netId, interface, uidRanges, secure, ACTION_DEL, 1016 !MODIFY_NON_UID_BASED_RULES); 1017} 1018 1019int RouteController::addInterfaceToDefaultNetwork(const char* interface, Permission permission) { 1020 return modifyDefaultNetwork(RTM_NEWRULE, interface, permission); 1021} 1022 1023int RouteController::removeInterfaceFromDefaultNetwork(const char* interface, 1024 Permission permission) { 1025 return modifyDefaultNetwork(RTM_DELRULE, interface, permission); 1026} 1027 1028int RouteController::addRoute(const char* interface, const char* destination, const char* nexthop, 1029 TableType tableType) { 1030 return modifyRoute(RTM_NEWROUTE, interface, destination, nexthop, tableType); 1031} 1032 1033int RouteController::removeRoute(const char* interface, const char* destination, 1034 const char* nexthop, TableType tableType) { 1035 return modifyRoute(RTM_DELROUTE, interface, destination, nexthop, tableType); 1036} 1037 1038int RouteController::enableTethering(const char* inputInterface, const char* outputInterface) { 1039 return modifyTetheredNetwork(RTM_NEWRULE, inputInterface, outputInterface); 1040} 1041 1042int RouteController::disableTethering(const char* inputInterface, const char* outputInterface) { 1043 return modifyTetheredNetwork(RTM_DELRULE, inputInterface, outputInterface); 1044} 1045 1046int RouteController::addVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface, 1047 Permission permission) { 1048 return modifyVpnFallthroughRule(RTM_NEWRULE, vpnNetId, physicalInterface, permission); 1049} 1050 1051int RouteController::removeVirtualNetworkFallthrough(unsigned vpnNetId, 1052 const char* physicalInterface, 1053 Permission permission) { 1054 return modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission); 1055} 1056 1057} // namespace net 1058} // namespace android 1059