blob: 312e10f95415fc1992649ad445be716d93f89e76 [file] [log] [blame]
Garrick Evansf0ab7132019-06-18 14:50:42 +09001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#ifndef PATCHPANEL_DATAPATH_H_
6#define PATCHPANEL_DATAPATH_H_
Garrick Evansf0ab7132019-06-18 14:50:42 +09007
Hugo Benichie8758b52020-04-03 14:49:01 +09008#include <net/route.h>
Hugo Benichi33860d72020-07-09 16:34:01 +09009#include <sys/types.h>
Hugo Benichie8758b52020-04-03 14:49:01 +090010
Hugo Benichifcf81022020-12-04 11:01:37 +090011#include <iostream>
Hugo Benichibb38bdd2021-05-14 10:36:11 +090012#include <map>
13#include <memory>
Hugo Benichi2a940542020-10-26 18:50:49 +090014#include <set>
Garrick Evansf0ab7132019-06-18 14:50:42 +090015#include <string>
Hugo Benichi2a940542020-10-26 18:50:49 +090016#include <vector>
Garrick Evansf0ab7132019-06-18 14:50:42 +090017
Hugo Benichi82ed5cf2020-09-08 21:30:22 +090018#include <gtest/gtest_prod.h> // for FRIEND_TEST
Garrick Evansf0ab7132019-06-18 14:50:42 +090019
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090020#include "patchpanel/firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090021#include "patchpanel/mac_address_generator.h"
22#include "patchpanel/minijailed_process_runner.h"
Hugo Benichi153c7112021-02-22 17:46:33 +090023#include "patchpanel/net_util.h"
Hugo Benichi8d622b52020-08-13 15:24:12 +090024#include "patchpanel/routing_service.h"
Jason Jeremy Imana183d7a2021-08-06 01:35:40 +090025#include "patchpanel/scoped_ns.h"
Garrick Evans3388a032020-03-24 11:25:55 +090026#include "patchpanel/subnet.h"
Hugo Benichif818c782021-04-10 00:09:50 +090027#include "patchpanel/system.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090028
Garrick Evans3388a032020-03-24 11:25:55 +090029namespace patchpanel {
Garrick Evansf0ab7132019-06-18 14:50:42 +090030
Hugo Benichiad5947b2021-09-03 16:56:40 +090031// filter INPUT chain for ingress port access rules controlled by
32// permission_broker.
33constexpr char kIngressPortFirewallChain[] = "ingress_port_firewall";
34// filter OUTPUT chain for egress port restriction rules controlled by
35// permission_broker.
36constexpr char kEgressPortFirewallChain[] = "egress_port_firewall";
37// nat PREROUTING chain for ingress DNAT forwarding rules controlled by
38// permission_broker.
39constexpr char kIngressPortForwardingChain[] = "ingress_port_forwarding";
40
Hugo Benichifcf81022020-12-04 11:01:37 +090041// Struct holding parameters for Datapath::StartRoutingNamespace requests.
42struct ConnectedNamespace {
Jie Jiangf6799312021-05-14 16:27:03 +090043 // The special pid which indicates this namespace is not attached to an
44 // associated process but should be/was created by `ip netns add`.
45 static constexpr pid_t kNewNetnsPid = -1;
46
Hugo Benichifcf81022020-12-04 11:01:37 +090047 // The pid of the client network namespace.
48 pid_t pid;
49 // The name attached to the client network namespace.
50 std::string netns_name;
Hugo Benichi93306e52020-12-04 16:08:00 +090051 // Source to which traffic from |host_ifname| will be attributed.
52 TrafficSource source;
Hugo Benichi600a9432021-07-06 11:57:29 +090053 // Interface name of the shill Device for routing outbound traffic from the
54 // client namespace. Empty if outbound traffic should be forwarded to the
55 // highest priority network (physical or virtual).
Hugo Benichifcf81022020-12-04 11:01:37 +090056 std::string outbound_ifname;
Hugo Benichi93306e52020-12-04 16:08:00 +090057 // If |outbound_ifname| is empty and |route_on_vpn| is false, the traffic from
58 // the client namespace will be routed to the highest priority physical
Hugo Benichi600a9432021-07-06 11:57:29 +090059 // network. If |outbound_ifname| is empty and |route_on_vpn| is true, the
Hugo Benichi93306e52020-12-04 16:08:00 +090060 // traffic will be routed through VPN connections. If |outbound_ifname|
Hugo Benichi600a9432021-07-06 11:57:29 +090061 // specifies a valid physical interface, |route_on_vpn| is ignored.
Hugo Benichi93306e52020-12-04 16:08:00 +090062 bool route_on_vpn;
Hugo Benichi600a9432021-07-06 11:57:29 +090063 // Name of the "local" veth interface visible on the host namespace.
Hugo Benichifcf81022020-12-04 11:01:37 +090064 std::string host_ifname;
Hugo Benichi600a9432021-07-06 11:57:29 +090065 // Name of the "remote" veth interface moved into the client namespace.
Hugo Benichifcf81022020-12-04 11:01:37 +090066 std::string peer_ifname;
67 // IPv4 subnet assigned to the client namespace.
68 std::unique_ptr<Subnet> peer_subnet;
Jason Jeremy Iman6a7c3952021-07-05 23:15:10 +090069 // MAC address of the "local" veth interface visible on the host namespace.
70 MacAddress host_mac_addr;
Hugo Benichi600a9432021-07-06 11:57:29 +090071 // MAC address of the "remote" veth interface.
Hugo Benichifcf81022020-12-04 11:01:37 +090072 MacAddress peer_mac_addr;
Jason Jeremy Iman6a7c3952021-07-05 23:15:10 +090073 // Interface name of the shill device for routing outbound traffic from the
74 // client namespace. This will be filled to keep track of the upstream
75 // interface if |outbound_ifname| is empty.
76 std::string tracked_outbound_ifname;
Hugo Benichifcf81022020-12-04 11:01:37 +090077};
78
Jason Jeremy Imanf4fb64f2021-04-20 21:54:19 +090079struct DnsRedirectionRule {
80 patchpanel::SetDnsRedirectionRuleRequest::RuleType type;
81 std::string input_ifname;
82 std::string proxy_address;
83 std::vector<std::string> nameservers;
84};
85
Hugo Benichifcf81022020-12-04 11:01:37 +090086std::ostream& operator<<(std::ostream& stream,
87 const ConnectedNamespace& nsinfo);
88
Jason Jeremy Imanf4fb64f2021-04-20 21:54:19 +090089std::ostream& operator<<(std::ostream& stream, const DnsRedirectionRule& rule);
90
Hugo Benichid82d8832020-08-14 10:05:03 +090091// Simple enum of bitmasks used for specifying a set of IP family values.
92enum IpFamily {
93 NONE = 0,
94 IPv4 = 1 << 0,
95 IPv6 = 1 << 1,
Taoyu Lia0727dc2020-09-24 19:54:59 +090096 Dual = IPv4 | IPv6, // (1 << 0) | (1 << 1);
Hugo Benichid82d8832020-08-14 10:05:03 +090097};
98
Garrick Evans54861622019-07-19 09:05:09 +090099// Returns for given interface name the host name of a ARC veth pair.
Garrick Evans2f581a02020-05-11 10:43:35 +0900100std::string ArcVethHostName(const std::string& ifname);
Garrick Evans54861622019-07-19 09:05:09 +0900101
Garrick Evans8a067562020-05-11 12:47:30 +0900102// Returns the ARC bridge interface name for the given interface.
103std::string ArcBridgeName(const std::string& ifname);
104
Garrick Evansf0ab7132019-06-18 14:50:42 +0900105// ARC networking data path configuration utility.
Garrick Evans54861622019-07-19 09:05:09 +0900106// IPV4 addresses are always specified in singular dotted-form (a.b.c.d)
107// (not in CIDR representation
Garrick Evansf0ab7132019-06-18 14:50:42 +0900108class Datapath {
109 public:
Hugo Benichi03be8962022-03-17 13:16:38 +0900110 explicit Datapath(System* system);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900111 // Provided for testing only.
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900112 Datapath(MinijailedProcessRunner* process_runner,
113 Firewall* firewall,
Hugo Benichif818c782021-04-10 00:09:50 +0900114 System* system);
Qijiang Fan6bc59e12020-11-11 02:51:06 +0900115 Datapath(const Datapath&) = delete;
116 Datapath& operator=(const Datapath&) = delete;
117
Garrick Evansf0ab7132019-06-18 14:50:42 +0900118 virtual ~Datapath() = default;
119
Hugo Benichibf811c62020-09-07 17:30:45 +0900120 // Start and stop the Datapath, creating or destroying the initial iptables
121 // setup needed for forwarding traffic from VMs and containers and for
122 // fwmark based routing.
123 virtual void Start();
124 virtual void Stop();
125
Hugo Benichi33860d72020-07-09 16:34:01 +0900126 // Attaches the name |netns_name| to a network namespace identified by
Jie Jiangf6799312021-05-14 16:27:03 +0900127 // |netns_pid|. If |netns_pid| is -1, a new namespace with name |netns_name|
128 // will be created instead. If |netns_name| had already been created, it will
129 // be deleted first.
Hugo Benichi33860d72020-07-09 16:34:01 +0900130 virtual bool NetnsAttachName(const std::string& netns_name, pid_t netns_pid);
131
132 // Deletes the name |netns_name| of a network namespace.
133 virtual bool NetnsDeleteName(const std::string& netns_name);
134
Garrick Evans8a949dc2019-07-18 16:17:53 +0900135 virtual bool AddBridge(const std::string& ifname,
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900136 uint32_t ipv4_addr,
137 uint32_t ipv4_prefix_len);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900138 virtual void RemoveBridge(const std::string& ifname);
139
Garrick Evans621ed262019-11-13 12:28:43 +0900140 virtual bool AddToBridge(const std::string& br_ifname,
141 const std::string& ifname);
142
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900143 // Adds a new TAP device.
144 // |name| may be empty, in which case a default device name will be used;
145 // it may be a template (e.g. vmtap%d), in which case the kernel will
146 // generate the name; or it may be fully defined. In all cases, upon success,
147 // the function returns the actual name of the interface.
Garrick Evans621ed262019-11-13 12:28:43 +0900148 // |mac_addr| and |ipv4_addr| should be null if this interface will be later
149 // bridged.
Garrick Evans4f9f5572019-11-26 10:25:16 +0900150 // If |user| is empty, no owner will be set
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900151 virtual std::string AddTAP(const std::string& name,
Garrick Evans621ed262019-11-13 12:28:43 +0900152 const MacAddress* mac_addr,
153 const SubnetAddress* ipv4_addr,
Garrick Evans4f9f5572019-11-26 10:25:16 +0900154 const std::string& user);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900155
156 // |ifname| must be the actual name of the interface.
157 virtual void RemoveTAP(const std::string& ifname);
158
159 // The following are iptables methods.
160 // When specified, |ipv4_addr| is always singlar dotted-form (a.b.c.d)
161 // IPv4 address (not a CIDR representation).
162
Hugo Benichi76675592020-04-08 14:29:57 +0900163 // Creates a virtual interface pair split across the current namespace and the
164 // namespace corresponding to |pid|, and set up the remote interface
165 // |peer_ifname| according // to the given parameters.
166 virtual bool ConnectVethPair(pid_t pid,
Hugo Benichi33860d72020-07-09 16:34:01 +0900167 const std::string& netns_name,
Hugo Benichi76675592020-04-08 14:29:57 +0900168 const std::string& veth_ifname,
169 const std::string& peer_ifname,
170 const MacAddress& remote_mac_addr,
171 uint32_t remote_ipv4_addr,
172 uint32_t remote_ipv4_prefix_len,
173 bool remote_multicast_flag);
174
Jason Jeremy Imana183d7a2021-08-06 01:35:40 +0900175 // Disable and re-enable IPv6.
176 virtual void RestartIPv6();
177
Garrick Evans54861622019-07-19 09:05:09 +0900178 virtual void RemoveInterface(const std::string& ifname);
179
Hugo Benichi954bae62021-04-09 09:12:30 +0900180 // Create an OUTPUT DROP rule for any locally originated traffic
Hugo Benichi321f23b2020-09-25 15:42:05 +0900181 // whose src IPv4 matches |src_ip| and would exit |oif|. This is mainly used
182 // for dropping Chrome webRTC traffic incorrectly bound on ARC and other
183 // guests virtual interfaces (chromium:898210).
184 virtual bool AddSourceIPv4DropRule(const std::string& oif,
185 const std::string& src_ip);
Hugo Benichi321f23b2020-09-25 15:42:05 +0900186
Hugo Benichi7c342672020-09-08 09:18:14 +0900187 // Creates a virtual ethernet interface pair shared with the client namespace
Hugo Benichifcf81022020-12-04 11:01:37 +0900188 // of |nsinfo.pid| and sets up routing outside and inside the client namespace
189 // for connecting the client namespace to the network.
190 bool StartRoutingNamespace(const ConnectedNamespace& nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900191 // Destroys the virtual ethernet interface, routing, and network namespace
Hugo Benichifcf81022020-12-04 11:01:37 +0900192 // name set for |nsinfo.netns_name| by StartRoutingNamespace. The default
193 // route set inside the |nsinfo.netns_name| by patchpanel is not destroyed and
194 // it is assumed the client will teardown the namespace.
195 void StopRoutingNamespace(const ConnectedNamespace& nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900196
Jason Jeremy Imanf4fb64f2021-04-20 21:54:19 +0900197 // Start or stop DNS traffic redirection to DNS proxy. The rules created
198 // depend on the type requested.
199 bool StartDnsRedirection(const DnsRedirectionRule& rule);
200 void StopDnsRedirection(const DnsRedirectionRule& rule);
201
Hugo Benichi8d622b52020-08-13 15:24:12 +0900202 // Sets up IPv4 SNAT, IP forwarding, and traffic marking for the given
Hugo Benichi600a9432021-07-06 11:57:29 +0900203 // downstream network interface |int_ifname| associated to |source|. if
204 // |ext_ifname| is empty, traffic from the downstream interface is implicitly
205 // routed through the highest priority physical network when |route_on_vpn| is
206 // false, or through the highest priority logical network when |route_on_vpn|
207 // is true. If |ext_ifname| is defined, traffic from the downstream interface
208 // is routed to |ext_ifname| and |route_on_vpn| is ignored. If |int_ifname| is
209 // associated to a connected namespace and a VPN is connected, an additional
210 // IPv4 VPN fwmark tagging bypass rule is needed to allow return traffic to
211 // reach to the IPv4 local source. |peer_ipv4_addr| is the address of the
212 // interface inside the connected namespace needed to create this rule. If
213 // |peer_ipv4_addr| is 0, no additional rule will be added.
Hugo Benichi8d622b52020-08-13 15:24:12 +0900214 virtual void StartRoutingDevice(const std::string& ext_ifname,
215 const std::string& int_ifname,
216 uint32_t int_ipv4_addr,
Hugo Benichi93306e52020-12-04 16:08:00 +0900217 TrafficSource source,
Jason Jeremy Iman72e61102021-04-23 03:37:14 +0900218 bool route_on_vpn,
219 uint32_t peer_ipv4_addr = 0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900220
221 // Removes IPv4 iptables, IP forwarding, and traffic marking for the given
Hugo Benichi600a9432021-07-06 11:57:29 +0900222 // downstream network interface |int_ifname|.
Hugo Benichi8d622b52020-08-13 15:24:12 +0900223 virtual void StopRoutingDevice(const std::string& ext_ifname,
224 const std::string& int_ifname,
225 uint32_t int_ipv4_addr,
Hugo Benichi93306e52020-12-04 16:08:00 +0900226 TrafficSource source,
227 bool route_on_vpn);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900228
Hugo Benichi76be34a2020-08-26 22:35:54 +0900229 // Starts or stops marking conntrack entries routed to |ext_ifname| with its
230 // associated fwmark routing tag. Once a conntrack entry is marked with the
Hugo Benichi600a9432021-07-06 11:57:29 +0900231 // fwmark routing tag of an upstream network interface, the connection will be
232 // pinned to that network interface if conntrack fwmark restore is set for the
233 // source.
Hugo Benichi76be34a2020-08-26 22:35:54 +0900234 virtual void StartConnectionPinning(const std::string& ext_ifname);
235 virtual void StopConnectionPinning(const std::string& ext_ifname);
Hugo Benichi2a940542020-10-26 18:50:49 +0900236 // Starts or stops VPN routing for:
Hugo Benichi600a9432021-07-06 11:57:29 +0900237 // - Local traffic from sockets of binaries running under uids eligible to be
238 // routed
Hugo Benichi2a940542020-10-26 18:50:49 +0900239 // through VPN connections. These uids are defined by |kLocalSourceTypes|
240 // in routing_service.h
Hugo Benichi600a9432021-07-06 11:57:29 +0900241 // - Forwarded traffic from downstream network interfaces tracking the
242 // default network.
Hugo Benichi2a940542020-10-26 18:50:49 +0900243 virtual void StartVpnRouting(const std::string& vpn_ifname);
244 virtual void StopVpnRouting(const std::string& vpn_ifname);
Hugo Benichi76be34a2020-08-26 22:35:54 +0900245
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900246 // Starts and stops VPN lockdown mode. When patchpanel VPN lockdown is enabled
247 // and no VPN connection exists, any non-ARC traffic that would be routed to a
248 // VPN connection is instead rejected in iptables. ARC traffic is ignored
249 // because Android already implements VPN lockdown.
250 virtual void SetVpnLockdown(bool enable_vpn_lockdown);
251
Taoyu Li90c13912019-11-26 17:56:54 +0900252 // Methods supporting IPv6 configuration for ARC.
Garrick Evans664a82f2019-12-17 12:18:05 +0900253 virtual bool MaskInterfaceFlags(const std::string& ifname,
254 uint16_t on,
255 uint16_t off = 0);
Garrick Evans260ff302019-07-25 11:22:50 +0900256
Garrick Evans260ff302019-07-25 11:22:50 +0900257 virtual bool AddIPv6HostRoute(const std::string& ifname,
258 const std::string& ipv6_addr,
259 int ipv6_prefix_len);
260 virtual void RemoveIPv6HostRoute(const std::string& ifname,
261 const std::string& ipv6_addr,
262 int ipv6_prefix_len);
263
Taoyu Lia0727dc2020-09-24 19:54:59 +0900264 virtual bool AddIPv6Address(const std::string& ifname,
265 const std::string& ipv6_addr);
266 virtual void RemoveIPv6Address(const std::string& ifname,
267 const std::string& ipv6_addr);
Garrick Evans260ff302019-07-25 11:22:50 +0900268
Hugo Benichie8758b52020-04-03 14:49:01 +0900269 // Adds (or deletes) a route to direct to |gateway_addr| the traffic destined
270 // to the subnet defined by |addr| and |netmask|.
Garrick Evans3d97a392020-02-21 15:24:37 +0900271 virtual bool AddIPv4Route(uint32_t gateway_addr,
272 uint32_t addr,
273 uint32_t netmask);
Hugo Benichie8758b52020-04-03 14:49:01 +0900274 virtual bool DeleteIPv4Route(uint32_t gateway_addr,
275 uint32_t addr,
276 uint32_t netmask);
277 // Adds (or deletes) a route to direct to |ifname| the traffic destined to the
278 // subnet defined by |addr| and |netmask|.
279 virtual bool AddIPv4Route(const std::string& ifname,
280 uint32_t addr,
281 uint32_t netmask);
282 virtual bool DeleteIPv4Route(const std::string& ifname,
283 uint32_t addr,
284 uint32_t netmask);
Garrick Evans3d97a392020-02-21 15:24:37 +0900285
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900286 // Adds (or deletes) an iptables rule for ADB port forwarding.
287 virtual bool AddAdbPortForwardRule(const std::string& ifname);
288 virtual void DeleteAdbPortForwardRule(const std::string& ifname);
289
290 // Adds (or deletes) an iptables rule for ADB port access.
291 virtual bool AddAdbPortAccessRule(const std::string& ifname);
292 virtual void DeleteAdbPortAccessRule(const std::string& ifname);
293
Damien Dejean40e15982021-05-21 07:11:53 +0000294 // Enables or disables netfilter conntrack helpers.
295 virtual bool SetConntrackHelpers(bool enable_helpers);
Hugo Benichi48ca4eb2021-06-03 15:42:42 +0900296 // Allows (or stops allowing) loopback IPv4 addresses as valid sources or
297 // destinations during IPv4 routing for |ifname|. This lets connections
298 // originated from guests like ARC or Crostini be accepted on the host and
299 // should be used carefully in conjunction with firewall port access rules to
300 // only allow very specific connection patterns.
301 virtual bool SetRouteLocalnet(const std::string& ifname, bool enable);
302 // Adds all |modules| into the kernel using modprobe.
303 virtual bool ModprobeAll(const std::vector<std::string>& modules);
Damien Dejean40e15982021-05-21 07:11:53 +0000304
Hugo Benichi62fd1252021-08-19 16:55:54 +0900305 // Create (or delete) DNAT rules for sending unsollicited traffic inbound on
306 // interface |ifname| to |ipv4_addr|. This is used for implementing
307 // transparent ARC inbound connections to Android Apps listening on the
308 // network.
309 virtual void AddInboundIPv4DNAT(const std::string& ifname,
310 const std::string& ipv4_addr);
311 virtual void RemoveInboundIPv4DNAT(const std::string& ifname,
312 const std::string& ipv4_addr);
313
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900314 // Create (or delete) DNAT rules for redirecting DNS queries from system
315 // services to the nameservers of a particular physical networks. These
316 // DNAT rules are only applied if a VPN is connected and allows system
317 // services to resolve hostnames even if a VPN application configures DNS
318 // addresses only routable through the VPN (b/178331695).
319 // TODO(b/171157837) Replaces these rules with the system DNS proxy.
320 bool AddRedirectDnsRule(const std::string& ifname,
321 const std::string dns_ipv4_addr);
322 bool RemoveRedirectDnsRule(const std::string& ifname);
323
Hugo Benichif0f55562021-04-02 15:25:02 +0900324 // Add, remove, or flush chain |chain| in table |table|.
325 bool AddChain(IpFamily family,
326 const std::string& table,
327 const std::string& name);
328 bool RemoveChain(IpFamily family,
329 const std::string& table,
330 const std::string& name);
331 bool FlushChain(IpFamily family,
332 const std::string& table,
333 const std::string& name);
Hugo Benichicd27f4e2020-11-19 18:32:23 +0900334 // Manipulates a chain |chain| in table |table|.
Hugo Benichia2ed4432021-06-08 00:21:49 +0900335 virtual bool ModifyChain(IpFamily family,
336 const std::string& table,
337 const std::string& op,
338 const std::string& chain,
339 bool log_failures = true);
Hugo Benichiddf00842020-11-20 10:24:08 +0900340 // Sends an iptables command for table |table|.
Hugo Benichia2ed4432021-06-08 00:21:49 +0900341 virtual bool ModifyIptables(IpFamily family,
342 const std::string& table,
343 const std::vector<std::string>& argv,
344 bool log_failures = true);
Hugo Benichi48ca4eb2021-06-03 15:42:42 +0900345 // Dumps the iptables chains rules for the table |table|. |family| must be
346 // either IPv4 or IPv6.
347 virtual std::string DumpIptables(IpFamily family, const std::string& table);
Garrick Evans260ff302019-07-25 11:22:50 +0900348
Hugo Benichi283a7812021-06-08 00:47:54 +0900349 // Changes firewall rules based on |request|, allowing ingress traffic to a
350 // port, forwarding ingress traffic to a port into ARC or Crostini, or
351 // restricting localhost ports for listen(). This function corresponds to
352 // the ModifyPortRule method of patchpanel DBus API.
353 virtual bool ModifyPortRule(const patchpanel::ModifyPortRuleRequest& request);
354
Garrick Evansf0ab7132019-06-18 14:50:42 +0900355 private:
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900356 // Attempts to flush all built-in iptables chains used by patchpanel, and to
357 // delete all additionals chains created by patchpanel for routing. Traffic
358 // accounting chains are not deleted.
359 void ResetIptables();
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900360 // Creates a virtual interface pair.
361 bool AddVirtualInterfacePair(const std::string& netns_name,
362 const std::string& veth_ifname,
363 const std::string& peer_ifname);
364 // Sets the configuration of an interface.
365 bool ConfigureInterface(const std::string& ifname,
366 const MacAddress& mac_addr,
367 uint32_t ipv4_addr,
368 uint32_t ipv4_prefix_len,
369 bool up,
370 bool enable_multicast);
371 // Sets the link status.
372 bool ToggleInterface(const std::string& ifname, bool up);
Jason Jeremy Imanf4fb64f2021-04-20 21:54:19 +0900373 bool ModifyChromeDnsRedirect(IpFamily family,
374 const DnsRedirectionRule& rule,
375 const std::string& op);
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900376 bool ModifyRedirectDnsDNATRule(const std::string& op,
377 const std::string& protocol,
378 const std::string& ifname,
379 const std::string& dns_ipv4_addr);
Jason Jeremy Iman1d0544c2021-11-05 12:10:34 +0900380 bool ModifyDnsProxyMasquerade(IpFamily family,
381 const std::string& op,
382 const std::string& chain);
Jason Jeremy Imanf4fb64f2021-04-20 21:54:19 +0900383 bool ModifyRedirectDnsJumpRule(IpFamily family,
384 const std::string& op,
385 const std::string& chain,
386 const std::string& ifname,
387 const std::string& target_chain,
388 Fwmark mark = {},
389 Fwmark mask = {},
390 bool redirect_on_mark = false);
391 bool ModifyDnsRedirectionSkipVpnRule(IpFamily family, const std::string& op);
392
393 // Create (or delete) DNAT rules for redirecting DNS queries to a DNS proxy.
394 bool ModifyDnsProxyDNAT(IpFamily family,
395 const DnsRedirectionRule& rule,
396 const std::string& op,
397 const std::string& ifname,
398 const std::string& chain);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900399
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900400 bool ModifyConnmarkSet(IpFamily family,
401 const std::string& chain,
402 const std::string& op,
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900403 Fwmark mark,
404 Fwmark mask);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900405 bool ModifyConnmarkRestore(IpFamily family,
406 const std::string& chain,
407 const std::string& op,
Hugo Benichi1af52392020-11-27 18:09:32 +0900408 const std::string& iif,
409 Fwmark mask);
410 bool ModifyConnmarkSave(IpFamily family,
411 const std::string& chain,
412 const std::string& op,
Hugo Benichi1af52392020-11-27 18:09:32 +0900413 Fwmark mask);
Hugo Benichi2a940542020-10-26 18:50:49 +0900414 bool ModifyFwmarkRoutingTag(const std::string& chain,
415 const std::string& op,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900416 Fwmark routing_mark);
417 bool ModifyFwmarkSourceTag(const std::string& chain,
418 const std::string& op,
Hugo Benichi9be19b12020-08-14 15:33:40 +0900419 TrafficSource source);
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900420 bool ModifyFwmarkDefaultLocalSourceTag(const std::string& op,
421 TrafficSource source);
422 bool ModifyFwmarkLocalSourceTag(const std::string& op,
423 const LocalSourceSpecs& source);
424 bool ModifyFwmark(IpFamily family,
425 const std::string& chain,
426 const std::string& op,
427 const std::string& iif,
428 const std::string& uid_name,
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900429 uint32_t classid,
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900430 Fwmark mark,
431 Fwmark mask,
432 bool log_failures = true);
Hugo Benichiff3cbcf2021-04-03 00:22:06 +0900433 bool ModifyJumpRule(IpFamily family,
434 const std::string& table,
435 const std::string& op,
436 const std::string& chain,
437 const std::string& target,
438 const std::string& iif,
439 const std::string& oif,
440 bool log_failures = true);
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900441 bool ModifyFwmarkVpnJumpRule(const std::string& chain,
442 const std::string& op,
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900443 Fwmark mark,
444 Fwmark mask);
Jason Jeremy Imanf4fb64f2021-04-20 21:54:19 +0900445 bool ModifyFwmarkSkipVpnJumpRule(const std::string& chain,
446 const std::string& op,
Hugo Benichi5fbb9362021-07-09 15:41:33 +0900447 const std::string& uid,
448 bool log_failures = true);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900449 bool ModifyRtentry(ioctl_req_t op, struct rtentry* route);
Hugo Benichid82d8832020-08-14 10:05:03 +0900450
Hugo Benichia2ed4432021-06-08 00:21:49 +0900451 std::unique_ptr<MinijailedProcessRunner> process_runner_;
Hugo Benichi283a7812021-06-08 00:47:54 +0900452 std::unique_ptr<Firewall> firewall_;
Hugo Benichi03be8962022-03-17 13:16:38 +0900453 // Owned by Manager
454 System* system_;
Garrick Evansf0ab7132019-06-18 14:50:42 +0900455
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900456 FRIEND_TEST(DatapathTest, AddInboundIPv4DNAT);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900457 FRIEND_TEST(DatapathTest, AddVirtualInterfacePair);
458 FRIEND_TEST(DatapathTest, ConfigureInterface);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900459 FRIEND_TEST(DatapathTest, RemoveInboundIPv4DNAT);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900460 FRIEND_TEST(DatapathTest, RemoveOutboundIPv4SNATMark);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900461 FRIEND_TEST(DatapathTest, ToggleInterface);
462
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900463 // A map used for remembering the interface index of an interface. This
464 // information is necessary when cleaning up iptables fwmark rules that
465 // directly references the interface index. When removing these rules on
466 // an RTM_DELLINK event, the interface index cannot be retrieved anymore.
Hugo Benichi600a9432021-07-06 11:57:29 +0900467 // A new entry is only added when a new upstream network interface appears,
468 // and entries are not removed.
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900469 // TODO(b/161507671) Rely on RoutingService to obtain this information once
470 // shill/routing_table.cc has been migrated to patchpanel.
471 std::map<std::string, int> if_nametoindex_;
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900472
473 // A map used for tracking the primary IPv4 dns address associated to a given
474 // Shill Device known by its interface name. This is used for redirecting
475 // DNS queries of system services when a VPN is connected.
476 std::map<std::string, std::string> physical_dns_addresses_;
Garrick Evansf0ab7132019-06-18 14:50:42 +0900477};
478
Garrick Evans3388a032020-03-24 11:25:55 +0900479} // namespace patchpanel
Garrick Evansf0ab7132019-06-18 14:50:42 +0900480
Garrick Evans3388a032020-03-24 11:25:55 +0900481#endif // PATCHPANEL_DATAPATH_H_