blob: 72afb25d1ac0522e0edcedab35cdc31d476ae6a2 [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
Garrick Evansf0ab7132019-06-18 14:50:42 +090011#include <string>
12
13#include <base/macros.h>
14
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090015#include "patchpanel/firewall.h"
Garrick Evans3388a032020-03-24 11:25:55 +090016#include "patchpanel/mac_address_generator.h"
17#include "patchpanel/minijailed_process_runner.h"
Hugo Benichi8d622b52020-08-13 15:24:12 +090018#include "patchpanel/routing_service.h"
Garrick Evans3388a032020-03-24 11:25:55 +090019#include "patchpanel/subnet.h"
Garrick Evansf0ab7132019-06-18 14:50:42 +090020
Garrick Evans3388a032020-03-24 11:25:55 +090021namespace patchpanel {
Garrick Evansf0ab7132019-06-18 14:50:42 +090022
Taoyu Li90c13912019-11-26 17:56:54 +090023// cros lint will yell to force using int16/int64 instead of long here, however
24// note that unsigned long IS the correct signature for ioctl in Linux kernel -
25// it's 32 bits on 32-bit platform and 64 bits on 64-bit one.
26using ioctl_req_t = unsigned long;
27typedef int (*ioctl_t)(int, ioctl_req_t, ...);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090028
Garrick Evans54861622019-07-19 09:05:09 +090029// Returns for given interface name the host name of a ARC veth pair.
Garrick Evans2f581a02020-05-11 10:43:35 +090030std::string ArcVethHostName(const std::string& ifname);
Garrick Evans54861622019-07-19 09:05:09 +090031
Garrick Evans8a067562020-05-11 12:47:30 +090032// Returns the ARC bridge interface name for the given interface.
33std::string ArcBridgeName(const std::string& ifname);
34
Garrick Evansf0ab7132019-06-18 14:50:42 +090035// ARC networking data path configuration utility.
Garrick Evans54861622019-07-19 09:05:09 +090036// IPV4 addresses are always specified in singular dotted-form (a.b.c.d)
37// (not in CIDR representation
Garrick Evansf0ab7132019-06-18 14:50:42 +090038class Datapath {
39 public:
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090040 // |process_runner| and |firewall| must not be null; it is not owned.
41 Datapath(MinijailedProcessRunner* process_runner, Firewall* firewall);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090042 // Provided for testing only.
Jason Jeremy Imana7273a32020-08-04 11:25:31 +090043 Datapath(MinijailedProcessRunner* process_runner,
44 Firewall* firewall,
45 ioctl_t ioctl_hook);
Garrick Evansf0ab7132019-06-18 14:50:42 +090046 virtual ~Datapath() = default;
47
Hugo Benichi33860d72020-07-09 16:34:01 +090048 // Attaches the name |netns_name| to a network namespace identified by
49 // |netns_pid|. If |netns_name| had already been created, it will be deleted
50 // first.
51 virtual bool NetnsAttachName(const std::string& netns_name, pid_t netns_pid);
52
53 // Deletes the name |netns_name| of a network namespace.
54 virtual bool NetnsDeleteName(const std::string& netns_name);
55
Garrick Evans8a949dc2019-07-18 16:17:53 +090056 virtual bool AddBridge(const std::string& ifname,
Garrick Evans7a1a9ee2020-01-28 11:03:57 +090057 uint32_t ipv4_addr,
58 uint32_t ipv4_prefix_len);
Garrick Evans8a949dc2019-07-18 16:17:53 +090059 virtual void RemoveBridge(const std::string& ifname);
60
Garrick Evans621ed262019-11-13 12:28:43 +090061 virtual bool AddToBridge(const std::string& br_ifname,
62 const std::string& ifname);
63
Garrick Evansc7ae82c2019-09-04 16:25:10 +090064 // Adds a new TAP device.
65 // |name| may be empty, in which case a default device name will be used;
66 // it may be a template (e.g. vmtap%d), in which case the kernel will
67 // generate the name; or it may be fully defined. In all cases, upon success,
68 // the function returns the actual name of the interface.
Garrick Evans621ed262019-11-13 12:28:43 +090069 // |mac_addr| and |ipv4_addr| should be null if this interface will be later
70 // bridged.
Garrick Evans4f9f5572019-11-26 10:25:16 +090071 // If |user| is empty, no owner will be set
Garrick Evansc7ae82c2019-09-04 16:25:10 +090072 virtual std::string AddTAP(const std::string& name,
Garrick Evans621ed262019-11-13 12:28:43 +090073 const MacAddress* mac_addr,
74 const SubnetAddress* ipv4_addr,
Garrick Evans4f9f5572019-11-26 10:25:16 +090075 const std::string& user);
Garrick Evansc7ae82c2019-09-04 16:25:10 +090076
77 // |ifname| must be the actual name of the interface.
78 virtual void RemoveTAP(const std::string& ifname);
79
80 // The following are iptables methods.
81 // When specified, |ipv4_addr| is always singlar dotted-form (a.b.c.d)
82 // IPv4 address (not a CIDR representation).
83
Hugo Benichi76675592020-04-08 14:29:57 +090084 // Creates a virtual interface pair split across the current namespace and the
85 // namespace corresponding to |pid|, and set up the remote interface
86 // |peer_ifname| according // to the given parameters.
87 virtual bool ConnectVethPair(pid_t pid,
Hugo Benichi33860d72020-07-09 16:34:01 +090088 const std::string& netns_name,
Hugo Benichi76675592020-04-08 14:29:57 +090089 const std::string& veth_ifname,
90 const std::string& peer_ifname,
91 const MacAddress& remote_mac_addr,
92 uint32_t remote_ipv4_addr,
93 uint32_t remote_ipv4_prefix_len,
94 bool remote_multicast_flag);
95
Garrick Evans2470caa2020-03-04 14:15:41 +090096 // Creates a virtual interface pair.
Hugo Benichi9ab5a052020-07-28 11:29:01 +090097 virtual bool AddVirtualInterfacePair(const std::string& netns_name,
Hugo Benichi33860d72020-07-09 16:34:01 +090098 const std::string& veth_ifname,
Garrick Evans2470caa2020-03-04 14:15:41 +090099 const std::string& peer_ifname);
100
101 // Sets the link status.
102 virtual bool ToggleInterface(const std::string& ifname, bool up);
103
104 // Sets the configuration of an interface.
105 virtual bool ConfigureInterface(const std::string& ifname,
106 const MacAddress& mac_addr,
107 uint32_t ipv4_addr,
108 uint32_t ipv4_prefix_len,
109 bool up,
110 bool enable_multicast);
111
Garrick Evans54861622019-07-19 09:05:09 +0900112 virtual void RemoveInterface(const std::string& ifname);
113
Hugo Benichi8d622b52020-08-13 15:24:12 +0900114 // Sets up IPv4 SNAT, IP forwarding, and traffic marking for the given
115 // virtual device |int_ifname| associated to |source|. if |ext_ifname| is
116 // empty, the device is implicitly routed through the highest priority
117 // network.
118 virtual void StartRoutingDevice(const std::string& ext_ifname,
119 const std::string& int_ifname,
120 uint32_t int_ipv4_addr,
121 TrafficSource source);
122
123 // Removes IPv4 iptables, IP forwarding, and traffic marking for the given
124 // virtual device |int_ifname|.
125 virtual void StopRoutingDevice(const std::string& ext_ifname,
126 const std::string& int_ifname,
127 uint32_t int_ipv4_addr,
128 TrafficSource source);
129
Garrick Evansf0ab7132019-06-18 14:50:42 +0900130 // Create (or delete) pre-routing rules allowing direct ingress on |ifname|
131 // to guest desintation |ipv4_addr|.
132 virtual bool AddInboundIPv4DNAT(const std::string& ifname,
133 const std::string& ipv4_addr);
134 virtual void RemoveInboundIPv4DNAT(const std::string& ifname,
135 const std::string& ipv4_addr);
136
137 // Create (or delete) a forwarding rule for |ifname|.
138 virtual bool AddOutboundIPv4(const std::string& ifname);
139 virtual void RemoveOutboundIPv4(const std::string& ifname);
140
Garrick Evansd291af62020-05-25 10:39:06 +0900141 // Creates (or deletes) the forwarding and postrouting rules for SNAT
142 // fwmarked IPv4 traffic.
143 virtual bool AddSNATMarkRules();
144 virtual void RemoveSNATMarkRules();
145
Garrick Evansff6e37f2020-05-25 10:54:47 +0900146 virtual bool AddInterfaceSNAT(const std::string& ifname);
147 virtual void RemoveInterfaceSNAT(const std::string& ifname);
148
Hugo Benichie8758b52020-04-03 14:49:01 +0900149 // Create (or delete) a mangle PREROUTING rule for marking IPv4 traffic
150 // outgoing of |ifname| with the SNAT fwmark value 0x1.
151 // TODO(hugobenichi) Refer to RoutingService to obtain the fwmark value and
152 // add a fwmark mask in the generated rule.
153 virtual bool AddOutboundIPv4SNATMark(const std::string& ifname);
154 virtual void RemoveOutboundIPv4SNATMark(const std::string& ifname);
155
Garrick Evansd291af62020-05-25 10:39:06 +0900156 // Create (or delete) a forward rule for established connections.
157 virtual bool AddForwardEstablishedRule();
158 virtual void RemoveForwardEstablishedRule();
159
Taoyu Li90c13912019-11-26 17:56:54 +0900160 // Methods supporting IPv6 configuration for ARC.
Garrick Evans664a82f2019-12-17 12:18:05 +0900161 virtual bool MaskInterfaceFlags(const std::string& ifname,
162 uint16_t on,
163 uint16_t off = 0);
Garrick Evans260ff302019-07-25 11:22:50 +0900164
Taoyu Li90c13912019-11-26 17:56:54 +0900165 virtual bool AddIPv6Forwarding(const std::string& ifname1,
166 const std::string& ifname2);
167 virtual void RemoveIPv6Forwarding(const std::string& ifname1,
168 const std::string& ifname2);
169
Garrick Evans260ff302019-07-25 11:22:50 +0900170 virtual bool AddIPv6HostRoute(const std::string& ifname,
171 const std::string& ipv6_addr,
172 int ipv6_prefix_len);
173 virtual void RemoveIPv6HostRoute(const std::string& ifname,
174 const std::string& ipv6_addr,
175 int ipv6_prefix_len);
176
177 virtual bool AddIPv6Neighbor(const std::string& ifname,
178 const std::string& ipv6_addr);
179 virtual void RemoveIPv6Neighbor(const std::string& ifname,
180 const std::string& ipv6_addr);
181
Hugo Benichie8758b52020-04-03 14:49:01 +0900182 // Adds (or deletes) a route to direct to |gateway_addr| the traffic destined
183 // to the subnet defined by |addr| and |netmask|.
Garrick Evans3d97a392020-02-21 15:24:37 +0900184 virtual bool AddIPv4Route(uint32_t gateway_addr,
185 uint32_t addr,
186 uint32_t netmask);
Hugo Benichie8758b52020-04-03 14:49:01 +0900187 virtual bool DeleteIPv4Route(uint32_t gateway_addr,
188 uint32_t addr,
189 uint32_t netmask);
190 // Adds (or deletes) a route to direct to |ifname| the traffic destined to the
191 // subnet defined by |addr| and |netmask|.
192 virtual bool AddIPv4Route(const std::string& ifname,
193 uint32_t addr,
194 uint32_t netmask);
195 virtual bool DeleteIPv4Route(const std::string& ifname,
196 uint32_t addr,
197 uint32_t netmask);
Garrick Evans3d97a392020-02-21 15:24:37 +0900198
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900199 // Adds (or deletes) an iptables rule for ADB port forwarding.
200 virtual bool AddAdbPortForwardRule(const std::string& ifname);
201 virtual void DeleteAdbPortForwardRule(const std::string& ifname);
202
203 // Adds (or deletes) an iptables rule for ADB port access.
204 virtual bool AddAdbPortAccessRule(const std::string& ifname);
205 virtual void DeleteAdbPortAccessRule(const std::string& ifname);
206
Garrick Evans260ff302019-07-25 11:22:50 +0900207 MinijailedProcessRunner& runner() const;
208
Garrick Evansf0ab7132019-06-18 14:50:42 +0900209 private:
210 MinijailedProcessRunner* process_runner_;
Jason Jeremy Imana7273a32020-08-04 11:25:31 +0900211 Firewall* firewall_;
Garrick Evansc7ae82c2019-09-04 16:25:10 +0900212 ioctl_t ioctl_;
Garrick Evansf0ab7132019-06-18 14:50:42 +0900213
Hugo Benichie8758b52020-04-03 14:49:01 +0900214 bool ModifyRtentry(unsigned long op, struct rtentry* route);
215
Garrick Evansf0ab7132019-06-18 14:50:42 +0900216 DISALLOW_COPY_AND_ASSIGN(Datapath);
217};
218
Garrick Evans3388a032020-03-24 11:25:55 +0900219} // namespace patchpanel
Garrick Evansf0ab7132019-06-18 14:50:42 +0900220
Garrick Evans3388a032020-03-24 11:25:55 +0900221#endif // PATCHPANEL_DATAPATH_H_