blob: 72b664b6caca6f4b31de4dd29fa818a66870e0ff [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
18#include <base/macros.h>
Hugo Benichi82ed5cf2020-09-08 21:30:22 +090019#include <gtest/gtest_prod.h> // for FRIEND_TEST
Garrick Evansf0ab7132019-06-18 14:50:42 +090020
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090021#include "patchpanel/firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090022#include "patchpanel/mac_address_generator.h"
23#include "patchpanel/minijailed_process_runner.h"
Hugo Benichi8d622b52020-08-13 15:24:12 +090024#include "patchpanel/routing_service.h"
Garrick Evans3388a032020-03-24 11:25:55 +090025#include "patchpanel/subnet.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090026
Garrick Evans3388a032020-03-24 11:25:55 +090027namespace patchpanel {
Garrick Evansf0ab7132019-06-18 14:50:42 +090028
Hugo Benichifcf81022020-12-04 11:01:37 +090029// Struct holding parameters for Datapath::StartRoutingNamespace requests.
30struct ConnectedNamespace {
Jie Jiangf6799312021-05-14 16:27:03 +090031 // The special pid which indicates this namespace is not attached to an
32 // associated process but should be/was created by `ip netns add`.
33 static constexpr pid_t kNewNetnsPid = -1;
34
Hugo Benichifcf81022020-12-04 11:01:37 +090035 // The pid of the client network namespace.
36 pid_t pid;
37 // The name attached to the client network namespace.
38 std::string netns_name;
Hugo Benichi93306e52020-12-04 16:08:00 +090039 // Source to which traffic from |host_ifname| will be attributed.
40 TrafficSource source;
Hugo Benichifcf81022020-12-04 11:01:37 +090041 // Name of the shill device for routing outbound traffic from the client
42 // namespace. Empty if outbound traffic should be forwarded to the highest
43 // priority network (physical or virtual).
44 std::string outbound_ifname;
Hugo Benichi93306e52020-12-04 16:08:00 +090045 // If |outbound_ifname| is empty and |route_on_vpn| is false, the traffic from
46 // the client namespace will be routed to the highest priority physical
47 // device. If |outbound_ifname| is empty and |route_on_vpn| is true, the
48 // traffic will be routed through VPN connections. If |outbound_ifname|
49 // specifies a valid physical device, |route_on_vpn| is ignored.
50 bool route_on_vpn;
Hugo Benichifcf81022020-12-04 11:01:37 +090051 // Name of the "local" veth device visible on the host namespace.
52 std::string host_ifname;
53 // Name of the "remote" veth device moved into the client namespace.
54 std::string peer_ifname;
55 // IPv4 subnet assigned to the client namespace.
56 std::unique_ptr<Subnet> peer_subnet;
57 // MAC address of the "remote" veth device.
58 MacAddress peer_mac_addr;
59};
60
61std::ostream& operator<<(std::ostream& stream,
62 const ConnectedNamespace& nsinfo);
63
Hugo Benichid82d8832020-08-14 10:05:03 +090064// Simple enum of bitmasks used for specifying a set of IP family values.
65enum IpFamily {
66 NONE = 0,
67 IPv4 = 1 << 0,
68 IPv6 = 1 << 1,
Taoyu Lia0727dc2020-09-24 19:54:59 +090069 Dual = IPv4 | IPv6, // (1 << 0) | (1 << 1);
Hugo Benichid82d8832020-08-14 10:05:03 +090070};
71
Taoyu Li90c13912019-11-26 17:56:54 +090072// cros lint will yell to force using int16/int64 instead of long here, however
73// note that unsigned long IS the correct signature for ioctl in Linux kernel -
74// it's 32 bits on 32-bit platform and 64 bits on 64-bit one.
Jie Jiang040ad0f2021-05-17 16:50:48 +090075using ioctl_req_t = unsigned long; // NOLINT(runtime/int)
Taoyu Li90c13912019-11-26 17:56:54 +090076typedef int (*ioctl_t)(int, ioctl_req_t, ...);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090077
Garrick Evans54861622019-07-19 09:05:09 +090078// Returns for given interface name the host name of a ARC veth pair.
Garrick Evans2f581a02020-05-11 10:43:35 +090079std::string ArcVethHostName(const std::string& ifname);
Garrick Evans54861622019-07-19 09:05:09 +090080
Garrick Evans8a067562020-05-11 12:47:30 +090081// Returns the ARC bridge interface name for the given interface.
82std::string ArcBridgeName(const std::string& ifname);
83
Garrick Evansf0ab7132019-06-18 14:50:42 +090084// ARC networking data path configuration utility.
Garrick Evans54861622019-07-19 09:05:09 +090085// IPV4 addresses are always specified in singular dotted-form (a.b.c.d)
86// (not in CIDR representation
Garrick Evansf0ab7132019-06-18 14:50:42 +090087class Datapath {
88 public:
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090089 // |process_runner| and |firewall| must not be null; it is not owned.
90 Datapath(MinijailedProcessRunner* process_runner, Firewall* firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090091 // Provided for testing only.
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090092 Datapath(MinijailedProcessRunner* process_runner,
93 Firewall* firewall,
94 ioctl_t ioctl_hook);
Qijiang Fan6bc59e12020-11-11 02:51:06 +090095 Datapath(const Datapath&) = delete;
96 Datapath& operator=(const Datapath&) = delete;
97
Garrick Evansf0ab7132019-06-18 14:50:42 +090098 virtual ~Datapath() = default;
99
Hugo Benichibf811c62020-09-07 17:30:45 +0900100 // Start and stop the Datapath, creating or destroying the initial iptables
101 // setup needed for forwarding traffic from VMs and containers and for
102 // fwmark based routing.
103 virtual void Start();
104 virtual void Stop();
105
Hugo Benichi33860d72020-07-09 16:34:01 +0900106 // Attaches the name |netns_name| to a network namespace identified by
Jie Jiangf6799312021-05-14 16:27:03 +0900107 // |netns_pid|. If |netns_pid| is -1, a new namespace with name |netns_name|
108 // will be created instead. If |netns_name| had already been created, it will
109 // be deleted first.
Hugo Benichi33860d72020-07-09 16:34:01 +0900110 virtual bool NetnsAttachName(const std::string& netns_name, pid_t netns_pid);
111
112 // Deletes the name |netns_name| of a network namespace.
113 virtual bool NetnsDeleteName(const std::string& netns_name);
114
Garrick Evans8a949dc2019-07-18 16:17:53 +0900115 virtual bool AddBridge(const std::string& ifname,
Garrick Evans7a1a9ee2020-01-28 11:03:57 +0900116 uint32_t ipv4_addr,
117 uint32_t ipv4_prefix_len);
Garrick Evans8a949dc2019-07-18 16:17:53 +0900118 virtual void RemoveBridge(const std::string& ifname);
119
Garrick Evans621ed262019-11-13 12:28:43 +0900120 virtual bool AddToBridge(const std::string& br_ifname,
121 const std::string& ifname);
122
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900123 // Adds a new TAP device.
124 // |name| may be empty, in which case a default device name will be used;
125 // it may be a template (e.g. vmtap%d), in which case the kernel will
126 // generate the name; or it may be fully defined. In all cases, upon success,
127 // the function returns the actual name of the interface.
Garrick Evans621ed262019-11-13 12:28:43 +0900128 // |mac_addr| and |ipv4_addr| should be null if this interface will be later
129 // bridged.
Garrick Evans4f9f5572019-11-26 10:25:16 +0900130 // If |user| is empty, no owner will be set
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900131 virtual std::string AddTAP(const std::string& name,
Garrick Evans621ed262019-11-13 12:28:43 +0900132 const MacAddress* mac_addr,
133 const SubnetAddress* ipv4_addr,
Garrick Evans4f9f5572019-11-26 10:25:16 +0900134 const std::string& user);
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900135
136 // |ifname| must be the actual name of the interface.
137 virtual void RemoveTAP(const std::string& ifname);
138
139 // The following are iptables methods.
140 // When specified, |ipv4_addr| is always singlar dotted-form (a.b.c.d)
141 // IPv4 address (not a CIDR representation).
142
Hugo Benichi76675592020-04-08 14:29:57 +0900143 // Creates a virtual interface pair split across the current namespace and the
144 // namespace corresponding to |pid|, and set up the remote interface
145 // |peer_ifname| according // to the given parameters.
146 virtual bool ConnectVethPair(pid_t pid,
Hugo Benichi33860d72020-07-09 16:34:01 +0900147 const std::string& netns_name,
Hugo Benichi76675592020-04-08 14:29:57 +0900148 const std::string& veth_ifname,
149 const std::string& peer_ifname,
150 const MacAddress& remote_mac_addr,
151 uint32_t remote_ipv4_addr,
152 uint32_t remote_ipv4_prefix_len,
153 bool remote_multicast_flag);
154
Garrick Evans54861622019-07-19 09:05:09 +0900155 virtual void RemoveInterface(const std::string& ifname);
156
Hugo Benichi954bae62021-04-09 09:12:30 +0900157 // Create an OUTPUT DROP rule for any locally originated traffic
Hugo Benichi321f23b2020-09-25 15:42:05 +0900158 // whose src IPv4 matches |src_ip| and would exit |oif|. This is mainly used
159 // for dropping Chrome webRTC traffic incorrectly bound on ARC and other
160 // guests virtual interfaces (chromium:898210).
161 virtual bool AddSourceIPv4DropRule(const std::string& oif,
162 const std::string& src_ip);
Hugo Benichi321f23b2020-09-25 15:42:05 +0900163
Hugo Benichi7c342672020-09-08 09:18:14 +0900164 // Creates a virtual ethernet interface pair shared with the client namespace
Hugo Benichifcf81022020-12-04 11:01:37 +0900165 // of |nsinfo.pid| and sets up routing outside and inside the client namespace
166 // for connecting the client namespace to the network.
167 bool StartRoutingNamespace(const ConnectedNamespace& nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900168 // Destroys the virtual ethernet interface, routing, and network namespace
Hugo Benichifcf81022020-12-04 11:01:37 +0900169 // name set for |nsinfo.netns_name| by StartRoutingNamespace. The default
170 // route set inside the |nsinfo.netns_name| by patchpanel is not destroyed and
171 // it is assumed the client will teardown the namespace.
172 void StopRoutingNamespace(const ConnectedNamespace& nsinfo);
Hugo Benichi7c342672020-09-08 09:18:14 +0900173
Hugo Benichi8d622b52020-08-13 15:24:12 +0900174 // Sets up IPv4 SNAT, IP forwarding, and traffic marking for the given
175 // virtual device |int_ifname| associated to |source|. if |ext_ifname| is
176 // empty, the device is implicitly routed through the highest priority
Hugo Benichibfc49112020-12-14 12:54:44 +0900177 // physical network when |route_on_vpn| is false, or through the highest
178 // priority logical network when |route_on_vpn| is true. If |ext_ifname| is
179 // defined, the device is routed to |ext_ifname| and |route_on_vpn| is
180 // ignored.
Jason Jeremy Iman72e61102021-04-23 03:37:14 +0900181 // If the device is associated to a connected namespace and a VPN is
182 // connected, an additional IPv4 VPN fwmark tagging bypass rule is needed
183 // to allow return traffic to reach to the IPv4 local source. |peer_ipv4_addr|
184 // is the address of the interface inside the connected namespace needed to
185 // create this rule. If |peer_ipv4_addr| is 0, no additional rule will be
186 // added.
Hugo Benichi8d622b52020-08-13 15:24:12 +0900187 virtual void StartRoutingDevice(const std::string& ext_ifname,
188 const std::string& int_ifname,
189 uint32_t int_ipv4_addr,
Hugo Benichi93306e52020-12-04 16:08:00 +0900190 TrafficSource source,
Jason Jeremy Iman72e61102021-04-23 03:37:14 +0900191 bool route_on_vpn,
192 uint32_t peer_ipv4_addr = 0);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900193
194 // Removes IPv4 iptables, IP forwarding, and traffic marking for the given
195 // virtual device |int_ifname|.
196 virtual void StopRoutingDevice(const std::string& ext_ifname,
197 const std::string& int_ifname,
198 uint32_t int_ipv4_addr,
Hugo Benichi93306e52020-12-04 16:08:00 +0900199 TrafficSource source,
200 bool route_on_vpn);
Hugo Benichi8d622b52020-08-13 15:24:12 +0900201
Hugo Benichi76be34a2020-08-26 22:35:54 +0900202 // Starts or stops marking conntrack entries routed to |ext_ifname| with its
203 // associated fwmark routing tag. Once a conntrack entry is marked with the
204 // fwmark routing tag of a external device, the connection will be pinned
205 // to that deviced if conntrack fwmark restore is set for the source.
206 virtual void StartConnectionPinning(const std::string& ext_ifname);
207 virtual void StopConnectionPinning(const std::string& ext_ifname);
Hugo Benichi2a940542020-10-26 18:50:49 +0900208 // Starts or stops VPN routing for:
209 // - Local sockets of binaries running under uids eligible to be routed
210 // through VPN connections. These uids are defined by |kLocalSourceTypes|
211 // in routing_service.h
212 // - Forwarded virtual devices tracking the default network.
213 virtual void StartVpnRouting(const std::string& vpn_ifname);
214 virtual void StopVpnRouting(const std::string& vpn_ifname);
Hugo Benichi76be34a2020-08-26 22:35:54 +0900215
Hugo Benichibb38bdd2021-05-14 10:36:11 +0900216 // Starts and stops VPN lockdown mode. When patchpanel VPN lockdown is enabled
217 // and no VPN connection exists, any non-ARC traffic that would be routed to a
218 // VPN connection is instead rejected in iptables. ARC traffic is ignored
219 // because Android already implements VPN lockdown.
220 virtual void SetVpnLockdown(bool enable_vpn_lockdown);
221
Taoyu Li90c13912019-11-26 17:56:54 +0900222 // Methods supporting IPv6 configuration for ARC.
Garrick Evans664a82f2019-12-17 12:18:05 +0900223 virtual bool MaskInterfaceFlags(const std::string& ifname,
224 uint16_t on,
225 uint16_t off = 0);
Garrick Evans260ff302019-07-25 11:22:50 +0900226
Hugo Benichid82d8832020-08-14 10:05:03 +0900227 // Convenience functions for enabling or disabling IPv6 forwarding in both
228 // directions between a pair of interfaces
Taoyu Li90c13912019-11-26 17:56:54 +0900229 virtual bool AddIPv6Forwarding(const std::string& ifname1,
230 const std::string& ifname2);
231 virtual void RemoveIPv6Forwarding(const std::string& ifname1,
232 const std::string& ifname2);
233
Garrick Evans260ff302019-07-25 11:22:50 +0900234 virtual bool AddIPv6HostRoute(const std::string& ifname,
235 const std::string& ipv6_addr,
236 int ipv6_prefix_len);
237 virtual void RemoveIPv6HostRoute(const std::string& ifname,
238 const std::string& ipv6_addr,
239 int ipv6_prefix_len);
240
Taoyu Lia0727dc2020-09-24 19:54:59 +0900241 virtual bool AddIPv6Address(const std::string& ifname,
242 const std::string& ipv6_addr);
243 virtual void RemoveIPv6Address(const std::string& ifname,
244 const std::string& ipv6_addr);
Garrick Evans260ff302019-07-25 11:22:50 +0900245
Hugo Benichie8758b52020-04-03 14:49:01 +0900246 // Adds (or deletes) a route to direct to |gateway_addr| the traffic destined
247 // to the subnet defined by |addr| and |netmask|.
Garrick Evans3d97a392020-02-21 15:24:37 +0900248 virtual bool AddIPv4Route(uint32_t gateway_addr,
249 uint32_t addr,
250 uint32_t netmask);
Hugo Benichie8758b52020-04-03 14:49:01 +0900251 virtual bool DeleteIPv4Route(uint32_t gateway_addr,
252 uint32_t addr,
253 uint32_t netmask);
254 // Adds (or deletes) a route to direct to |ifname| the traffic destined to the
255 // subnet defined by |addr| and |netmask|.
256 virtual bool AddIPv4Route(const std::string& ifname,
257 uint32_t addr,
258 uint32_t netmask);
259 virtual bool DeleteIPv4Route(const std::string& ifname,
260 uint32_t addr,
261 uint32_t netmask);
Garrick Evans3d97a392020-02-21 15:24:37 +0900262
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900263 // Adds (or deletes) an iptables rule for ADB port forwarding.
264 virtual bool AddAdbPortForwardRule(const std::string& ifname);
265 virtual void DeleteAdbPortForwardRule(const std::string& ifname);
266
267 // Adds (or deletes) an iptables rule for ADB port access.
268 virtual bool AddAdbPortAccessRule(const std::string& ifname);
269 virtual void DeleteAdbPortAccessRule(const std::string& ifname);
270
Damien Dejean40e15982021-05-21 07:11:53 +0000271 // Enables or disables netfilter conntrack helpers.
272 virtual bool SetConntrackHelpers(bool enable_helpers);
273
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900274 // Create (or delete) DNAT rules for redirecting DNS queries from system
275 // services to the nameservers of a particular physical networks. These
276 // DNAT rules are only applied if a VPN is connected and allows system
277 // services to resolve hostnames even if a VPN application configures DNS
278 // addresses only routable through the VPN (b/178331695).
279 // TODO(b/171157837) Replaces these rules with the system DNS proxy.
280 bool AddRedirectDnsRule(const std::string& ifname,
281 const std::string dns_ipv4_addr);
282 bool RemoveRedirectDnsRule(const std::string& ifname);
283
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900284 // Set or override the interface name to index mapping for |ifname|.
285 // Only used for testing.
286 void SetIfnameIndex(const std::string& ifname, int ifindex);
287
Hugo Benichif0f55562021-04-02 15:25:02 +0900288 // Add, remove, or flush chain |chain| in table |table|.
289 bool AddChain(IpFamily family,
290 const std::string& table,
291 const std::string& name);
292 bool RemoveChain(IpFamily family,
293 const std::string& table,
294 const std::string& name);
295 bool FlushChain(IpFamily family,
296 const std::string& table,
297 const std::string& name);
Hugo Benichicd27f4e2020-11-19 18:32:23 +0900298 // Manipulates a chain |chain| in table |table|.
299 bool ModifyChain(IpFamily family,
300 const std::string& table,
301 const std::string& op,
302 const std::string& chain,
303 bool log_failures = true);
Hugo Benichiddf00842020-11-20 10:24:08 +0900304 // Sends an iptables command for table |table|.
305 bool ModifyIptables(IpFamily family,
306 const std::string& table,
307 const std::vector<std::string>& argv,
308 bool log_failures = true);
Hugo Benichicd27f4e2020-11-19 18:32:23 +0900309
Garrick Evans260ff302019-07-25 11:22:50 +0900310 MinijailedProcessRunner& runner() const;
311
Garrick Evansf0ab7132019-06-18 14:50:42 +0900312 private:
Hugo Benichi91ee09f2020-12-03 22:24:22 +0900313 // Attempts to flush all built-in iptables chains used by patchpanel, and to
314 // delete all additionals chains created by patchpanel for routing. Traffic
315 // accounting chains are not deleted.
316 void ResetIptables();
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900317 // Creates a virtual interface pair.
318 bool AddVirtualInterfacePair(const std::string& netns_name,
319 const std::string& veth_ifname,
320 const std::string& peer_ifname);
321 // Sets the configuration of an interface.
322 bool ConfigureInterface(const std::string& ifname,
323 const MacAddress& mac_addr,
324 uint32_t ipv4_addr,
325 uint32_t ipv4_prefix_len,
326 bool up,
327 bool enable_multicast);
328 // Sets the link status.
329 bool ToggleInterface(const std::string& ifname, bool up);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900330 // Create (or delete) pre-routing rules allowing direct ingress on |ifname|
331 // to guest destination |ipv4_addr|.
332 bool AddInboundIPv4DNAT(const std::string& ifname,
333 const std::string& ipv4_addr);
334 void RemoveInboundIPv4DNAT(const std::string& ifname,
335 const std::string& ipv4_addr);
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900336 bool ModifyRedirectDnsDNATRule(const std::string& op,
337 const std::string& protocol,
338 const std::string& ifname,
339 const std::string& dns_ipv4_addr);
340 bool ModifyRedirectDnsJumpRule(const std::string& op);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900341
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900342 bool ModifyConnmarkSet(IpFamily family,
343 const std::string& chain,
344 const std::string& op,
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900345 Fwmark mark,
346 Fwmark mask);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900347 bool ModifyConnmarkRestore(IpFamily family,
348 const std::string& chain,
349 const std::string& op,
Hugo Benichi1af52392020-11-27 18:09:32 +0900350 const std::string& iif,
351 Fwmark mask);
352 bool ModifyConnmarkSave(IpFamily family,
353 const std::string& chain,
354 const std::string& op,
Hugo Benichi1af52392020-11-27 18:09:32 +0900355 Fwmark mask);
Hugo Benichi2a940542020-10-26 18:50:49 +0900356 bool ModifyFwmarkRoutingTag(const std::string& chain,
357 const std::string& op,
Hugo Benichid872d3d2021-03-29 10:20:53 +0900358 Fwmark routing_mark);
359 bool ModifyFwmarkSourceTag(const std::string& chain,
360 const std::string& op,
Hugo Benichi9be19b12020-08-14 15:33:40 +0900361 TrafficSource source);
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900362 bool ModifyFwmarkDefaultLocalSourceTag(const std::string& op,
363 TrafficSource source);
364 bool ModifyFwmarkLocalSourceTag(const std::string& op,
365 const LocalSourceSpecs& source);
366 bool ModifyFwmark(IpFamily family,
367 const std::string& chain,
368 const std::string& op,
369 const std::string& iif,
370 const std::string& uid_name,
Hugo Benichi7e3b1fc2020-11-19 15:47:05 +0900371 uint32_t classid,
Hugo Benichi3a9162b2020-09-09 15:47:40 +0900372 Fwmark mark,
373 Fwmark mask,
374 bool log_failures = true);
Hugo Benichid82d8832020-08-14 10:05:03 +0900375 bool ModifyIpForwarding(IpFamily family,
376 const std::string& op,
377 const std::string& iif,
378 const std::string& oif,
379 bool log_failures = true);
Hugo Benichiff3cbcf2021-04-03 00:22:06 +0900380 bool ModifyJumpRule(IpFamily family,
381 const std::string& table,
382 const std::string& op,
383 const std::string& chain,
384 const std::string& target,
385 const std::string& iif,
386 const std::string& oif,
387 bool log_failures = true);
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900388 bool ModifyFwmarkVpnJumpRule(const std::string& chain,
389 const std::string& op,
Hugo Benichi3ef370b2020-11-16 19:07:17 +0900390 Fwmark mark,
391 Fwmark mask);
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900392 bool ModifyRtentry(ioctl_req_t op, struct rtentry* route);
Hugo Benichi8c526e92021-03-25 14:59:59 +0900393 // Uses if_nametoindex to return the interface index of |ifname|. If |ifname|
394 // does not exist anymore, looks up the cache |if_nametoindex_|. It is
395 // incorrect to use this function in situations where the interface has been
396 // recreated and the older value must be recovered (b/183679000).
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900397 int FindIfIndex(const std::string& ifname);
Hugo Benichid82d8832020-08-14 10:05:03 +0900398
Garrick Evansf0ab7132019-06-18 14:50:42 +0900399 MinijailedProcessRunner* process_runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900400 Firewall* firewall_;
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900401 ioctl_t ioctl_;
Garrick Evansf0ab7132019-06-18 14:50:42 +0900402
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900403 FRIEND_TEST(DatapathTest, AddInboundIPv4DNAT);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900404 FRIEND_TEST(DatapathTest, AddVirtualInterfacePair);
405 FRIEND_TEST(DatapathTest, ConfigureInterface);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900406 FRIEND_TEST(DatapathTest, RemoveInboundIPv4DNAT);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900407 FRIEND_TEST(DatapathTest, RemoveOutboundIPv4SNATMark);
Hugo Benichi82ed5cf2020-09-08 21:30:22 +0900408 FRIEND_TEST(DatapathTest, ToggleInterface);
409
Hugo Benichiaf9d8a72020-08-26 13:28:13 +0900410 // A map used for remembering the interface index of an interface. This
411 // information is necessary when cleaning up iptables fwmark rules that
412 // directly references the interface index. When removing these rules on
413 // an RTM_DELLINK event, the interface index cannot be retrieved anymore.
414 // A new entry is only added when a new physical device appears, and entries
415 // are not removed.
416 // TODO(b/161507671) Rely on RoutingService to obtain this information once
417 // shill/routing_table.cc has been migrated to patchpanel.
418 std::map<std::string, int> if_nametoindex_;
Hugo Benichi1e0656f2021-02-15 15:43:38 +0900419
420 // A map used for tracking the primary IPv4 dns address associated to a given
421 // Shill Device known by its interface name. This is used for redirecting
422 // DNS queries of system services when a VPN is connected.
423 std::map<std::string, std::string> physical_dns_addresses_;
Garrick Evansf0ab7132019-06-18 14:50:42 +0900424};
425
Garrick Evans3388a032020-03-24 11:25:55 +0900426} // namespace patchpanel
Garrick Evansf0ab7132019-06-18 14:50:42 +0900427
Garrick Evans3388a032020-03-24 11:25:55 +0900428#endif // PATCHPANEL_DATAPATH_H_