OSDN Git Service

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